@crab-dev/wake 0.1.21 → 0.1.22
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/CHANGELOG.md +11 -0
- package/bin/terminal.mjs +20 -4
- package/bin/wake.mjs +418 -0
- package/index.cjs +197 -0
- package/index.d.ts +254 -0
- package/index.mjs +3 -0
- package/loader.cjs +19 -2
- package/package.json +25 -9
- package/test-context-internal.cjs +30 -0
- package/test-react.cjs +60 -0
- package/test-react.d.ts +162 -0
- package/test-react.mjs +29 -0
- package/test.cjs +98 -0
- package/test.d.ts +265 -0
- package/test.mjs +15 -0
package/index.cjs
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const { EventEmitter } = require('node:events')
|
|
4
4
|
const { loadNative } = require('./loader.cjs')
|
|
5
|
+
const {
|
|
6
|
+
registerTestContext,
|
|
7
|
+
setTestContextFatalError,
|
|
8
|
+
} = require('./test-context-internal.cjs')
|
|
5
9
|
const {
|
|
6
10
|
WakeError,
|
|
7
11
|
fromNativeError,
|
|
@@ -25,6 +29,196 @@ async function bundle(options) {
|
|
|
25
29
|
return invoke(native.bundle(JSON.stringify(value), signal))
|
|
26
30
|
}
|
|
27
31
|
|
|
32
|
+
function splitTestOptions(options) {
|
|
33
|
+
try {
|
|
34
|
+
return splitOptions(options)
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (error instanceof WakeError && error.code === 'WAKE_CONFIG') {
|
|
37
|
+
throw new WakeError('WAKE_TEST_CONFIG', error.message, { cause: error })
|
|
38
|
+
}
|
|
39
|
+
throw error
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function runTests(options) {
|
|
44
|
+
const [value, signal] = splitTestOptions(options)
|
|
45
|
+
return invoke(native.runTests(
|
|
46
|
+
JSON.stringify(value),
|
|
47
|
+
signal,
|
|
48
|
+
native.__wakeTestHostPath,
|
|
49
|
+
))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class TestContext extends EventEmitter {
|
|
53
|
+
#native
|
|
54
|
+
#closed = false
|
|
55
|
+
#eventPoll
|
|
56
|
+
|
|
57
|
+
constructor(handle) {
|
|
58
|
+
super()
|
|
59
|
+
this.#native = handle
|
|
60
|
+
registerTestContext(this, handle)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get closed() {
|
|
64
|
+
return this.#closed || this.#native.closed
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get watching() {
|
|
68
|
+
return Boolean(this.#native.watching)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async run() {
|
|
72
|
+
if (this.closed) throw new WakeError('WAKE_TEST_CONTEXT', 'TestContext has already been closed')
|
|
73
|
+
try {
|
|
74
|
+
const result = await invoke(this.#native.run())
|
|
75
|
+
this.#flushEvents()
|
|
76
|
+
return result
|
|
77
|
+
} catch (error) {
|
|
78
|
+
this.#flushEvents()
|
|
79
|
+
throw error
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
startWatch() {
|
|
84
|
+
if (this.closed) throw new WakeError('WAKE_TEST_CONTEXT', 'TestContext has already been closed')
|
|
85
|
+
try {
|
|
86
|
+
this.#native.startWatch()
|
|
87
|
+
this.#flushEvents()
|
|
88
|
+
this.#startEventPoll()
|
|
89
|
+
return this
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw fromNativeError(error)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
stopWatch() {
|
|
96
|
+
if (this.closed) return this
|
|
97
|
+
try {
|
|
98
|
+
this.#native.stopWatch()
|
|
99
|
+
this.#flushEvents()
|
|
100
|
+
this.#stopEventPoll()
|
|
101
|
+
return this
|
|
102
|
+
} catch (error) {
|
|
103
|
+
throw fromNativeError(error)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async close() {
|
|
108
|
+
if (this.#closed) return
|
|
109
|
+
this.#closed = true
|
|
110
|
+
this.#stopEventPoll()
|
|
111
|
+
try {
|
|
112
|
+
await invoke(this.#native.close())
|
|
113
|
+
} finally {
|
|
114
|
+
this.#flushEvents()
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async [Symbol.asyncDispose]() {
|
|
119
|
+
await this.close()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#flushEvents() {
|
|
123
|
+
this.#dispatchEvents(this.#readEvents())
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#readEvents() {
|
|
127
|
+
let events
|
|
128
|
+
try {
|
|
129
|
+
events = JSON.parse(this.#native.eventsJson())
|
|
130
|
+
} catch (cause) {
|
|
131
|
+
const detail = cause instanceof Error ? cause.message : String(cause)
|
|
132
|
+
throw new WakeError(
|
|
133
|
+
'WAKE_TEST_HOST',
|
|
134
|
+
`Wake returned an invalid test event stream: ${detail}`,
|
|
135
|
+
{ cause },
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
if (!Array.isArray(events)) {
|
|
139
|
+
throw new WakeError('WAKE_TEST_HOST', 'Wake returned a non-array test event stream')
|
|
140
|
+
}
|
|
141
|
+
return events
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#dispatchEvents(events) {
|
|
145
|
+
for (const event of events) {
|
|
146
|
+
switch (event.type) {
|
|
147
|
+
case 'runStart':
|
|
148
|
+
this.emit('runStart', { runId: event.runId, watching: event.watching })
|
|
149
|
+
break
|
|
150
|
+
case 'testCaseResult':
|
|
151
|
+
this.emit('testCaseResult', {
|
|
152
|
+
runId: event.runId,
|
|
153
|
+
suiteId: event.suiteId,
|
|
154
|
+
result: event.result,
|
|
155
|
+
})
|
|
156
|
+
break
|
|
157
|
+
case 'suiteResult':
|
|
158
|
+
this.emit('suiteResult', {
|
|
159
|
+
runId: event.runId,
|
|
160
|
+
result: event.result,
|
|
161
|
+
})
|
|
162
|
+
break
|
|
163
|
+
case 'diagnostic':
|
|
164
|
+
this.emit('diagnostic', event.diagnostic)
|
|
165
|
+
break
|
|
166
|
+
case 'runComplete':
|
|
167
|
+
this.emit('runComplete', event.result)
|
|
168
|
+
break
|
|
169
|
+
case 'closed':
|
|
170
|
+
this.emit('closed')
|
|
171
|
+
break
|
|
172
|
+
default:
|
|
173
|
+
throw new WakeError('WAKE_TEST_HOST', `Unknown test-host event: ${String(event.type)}`)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#startEventPoll() {
|
|
179
|
+
if (this.#eventPoll) return
|
|
180
|
+
this.#eventPoll = setInterval(() => {
|
|
181
|
+
let events
|
|
182
|
+
try {
|
|
183
|
+
events = this.#readEvents()
|
|
184
|
+
} catch (error) {
|
|
185
|
+
this.#stopEventPoll()
|
|
186
|
+
const fatalError = error instanceof WakeError
|
|
187
|
+
? error
|
|
188
|
+
: new WakeError('WAKE_TEST_HOST', error instanceof Error ? error.message : String(error), {
|
|
189
|
+
cause: error,
|
|
190
|
+
})
|
|
191
|
+
setTestContextFatalError(this, fatalError)
|
|
192
|
+
// Host terminals are drained as ordered native events before this error becomes visible;
|
|
193
|
+
// closing then supplies the final public `closed` event without fabricating a duplicate
|
|
194
|
+
// JavaScript diagnostic.
|
|
195
|
+
void this.close().catch(() => {})
|
|
196
|
+
return
|
|
197
|
+
}
|
|
198
|
+
// User listeners execute outside the native/protocol error boundary. Their exceptions are
|
|
199
|
+
// ordinary EventEmitter failures and must never be relabeled as WAKE_TEST_HOST.
|
|
200
|
+
this.#dispatchEvents(events)
|
|
201
|
+
}, 25)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
#stopEventPoll() {
|
|
205
|
+
if (!this.#eventPoll) return
|
|
206
|
+
clearInterval(this.#eventPoll)
|
|
207
|
+
this.#eventPoll = undefined
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function createTestContext(options) {
|
|
212
|
+
const [value] = splitTestOptions(options)
|
|
213
|
+
try {
|
|
214
|
+
return new TestContext(
|
|
215
|
+
native.createTestContext(JSON.stringify(value), native.__wakeTestHostPath),
|
|
216
|
+
)
|
|
217
|
+
} catch (error) {
|
|
218
|
+
throw fromNativeError(error)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
28
222
|
async function buildLibrary(options) {
|
|
29
223
|
const [value, signal] = splitOptions(options)
|
|
30
224
|
return invoke(native.buildLibrary(JSON.stringify(value), signal))
|
|
@@ -208,14 +402,17 @@ function startDocsDevServer(options) {
|
|
|
208
402
|
module.exports = {
|
|
209
403
|
BuildContext,
|
|
210
404
|
DevServer,
|
|
405
|
+
TestContext,
|
|
211
406
|
WakeError,
|
|
212
407
|
build,
|
|
213
408
|
buildLibrary,
|
|
214
409
|
buildDocs,
|
|
215
410
|
bundle,
|
|
411
|
+
runTests,
|
|
216
412
|
generateCssToken,
|
|
217
413
|
generateDocgen,
|
|
218
414
|
createBuildContext,
|
|
415
|
+
createTestContext,
|
|
219
416
|
startDevServer,
|
|
220
417
|
startDocsDevServer,
|
|
221
418
|
version,
|
package/index.d.ts
CHANGED
|
@@ -20,6 +20,23 @@ export type WakeErrorCode =
|
|
|
20
20
|
| 'WAKE_LIBRARY_BUILD'
|
|
21
21
|
| 'WAKE_LIBRARY_TYPE'
|
|
22
22
|
| 'WAKE_LIBRARY_OUTPUT'
|
|
23
|
+
| 'WAKE_TEST_CONFIG'
|
|
24
|
+
| 'WAKE_TEST_DISCOVERY'
|
|
25
|
+
| 'WAKE_TEST_RUNTIME'
|
|
26
|
+
| 'WAKE_TEST_TIMEOUT'
|
|
27
|
+
| 'WAKE_TEST_SNAPSHOT'
|
|
28
|
+
| 'WAKE_TEST_COVERAGE'
|
|
29
|
+
| 'WAKE_TEST_HOST'
|
|
30
|
+
| 'WAKE_TEST_UNSUPPORTED'
|
|
31
|
+
| 'WAKE_TEST_CONTEXT'
|
|
32
|
+
| 'WAKE_TEST_DOM'
|
|
33
|
+
| 'WAKE_TEST_BROWSER'
|
|
34
|
+
| 'WAKE_TEST_REACT_VERSION'
|
|
35
|
+
| 'WAKE_TEST_NETWORK'
|
|
36
|
+
| 'WAKE_TEST_LEAK'
|
|
37
|
+
| 'WAKE_TEST_BUSY'
|
|
38
|
+
| 'WAKE_TEST_UNKNOWN_RUN'
|
|
39
|
+
| 'WAKE_TEST_UNKNOWN_WATCH'
|
|
23
40
|
|
|
24
41
|
export interface DiagnosticLocation {
|
|
25
42
|
/** One-based source line. */
|
|
@@ -66,6 +83,238 @@ export interface BuildOptions extends ProjectOptions {
|
|
|
66
83
|
sourceMap?: boolean
|
|
67
84
|
}
|
|
68
85
|
|
|
86
|
+
export type TestEnvironment = 'auto' | 'dom' | 'browser'
|
|
87
|
+
export type TestReporter = 'pretty' | 'json' | 'junit'
|
|
88
|
+
export type SnapshotUpdateMode = 'none' | 'new' | 'all'
|
|
89
|
+
export type TestWorkers = number | 'auto' | `${number}%`
|
|
90
|
+
|
|
91
|
+
export interface TestOptions {
|
|
92
|
+
root?: string
|
|
93
|
+
patterns?: string[]
|
|
94
|
+
namePattern?: string
|
|
95
|
+
projects?: string[]
|
|
96
|
+
environment?: TestEnvironment
|
|
97
|
+
watch?: boolean
|
|
98
|
+
changed?: boolean
|
|
99
|
+
related?: string[]
|
|
100
|
+
coverage?: boolean
|
|
101
|
+
updateSnapshots?: SnapshotUpdateMode
|
|
102
|
+
serial?: boolean
|
|
103
|
+
workers?: TestWorkers
|
|
104
|
+
bail?: number
|
|
105
|
+
shard?: `${number}/${number}`
|
|
106
|
+
seed?: string
|
|
107
|
+
shuffle?: boolean
|
|
108
|
+
reporter?: TestReporter
|
|
109
|
+
output?: string
|
|
110
|
+
allowNoTests?: boolean
|
|
111
|
+
browserPath?: string
|
|
112
|
+
headful?: boolean
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export type TestCaseStatus = 'passed' | 'failed' | 'skipped' | 'todo'
|
|
116
|
+
export type TestSuiteStatus = 'passed' | 'failed' | 'skipped'
|
|
117
|
+
export type TestTerminationReason =
|
|
118
|
+
| 'completed'
|
|
119
|
+
| 'cancelled'
|
|
120
|
+
| 'bail'
|
|
121
|
+
| 'watch-restart'
|
|
122
|
+
| 'host-crash'
|
|
123
|
+
| 'timeout'
|
|
124
|
+
| 'oom'
|
|
125
|
+
| 'internal-error'
|
|
126
|
+
|
|
127
|
+
export interface TestLocation {
|
|
128
|
+
path: string
|
|
129
|
+
line: number
|
|
130
|
+
column: number
|
|
131
|
+
endLine: number | null
|
|
132
|
+
endColumn: number | null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface TestDiff {
|
|
136
|
+
expected: string | null
|
|
137
|
+
received: string | null
|
|
138
|
+
unified: string | null
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface TestFailure {
|
|
142
|
+
message: string
|
|
143
|
+
code: string | null
|
|
144
|
+
stack: string | null
|
|
145
|
+
location: TestLocation | null
|
|
146
|
+
diff: TestDiff | null
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface TestCaseResult {
|
|
150
|
+
id: string
|
|
151
|
+
name: string
|
|
152
|
+
fullName: string
|
|
153
|
+
status: TestCaseStatus
|
|
154
|
+
durationMs: number
|
|
155
|
+
assertions: number
|
|
156
|
+
attempts: number
|
|
157
|
+
location: TestLocation | null
|
|
158
|
+
failures: TestFailure[]
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface SnapshotSummary {
|
|
162
|
+
added: number
|
|
163
|
+
matched: number
|
|
164
|
+
unmatched: number
|
|
165
|
+
updated: number
|
|
166
|
+
obsolete: number
|
|
167
|
+
filesRemoved: number
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface CoverageMetric {
|
|
171
|
+
covered: number
|
|
172
|
+
total: number
|
|
173
|
+
percent: number
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface CoverageMetrics {
|
|
177
|
+
lines: CoverageMetric
|
|
178
|
+
functions: CoverageMetric
|
|
179
|
+
blocks: CoverageMetric
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface CoverageFile extends CoverageMetrics {
|
|
183
|
+
path: string
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface CoverageResult {
|
|
187
|
+
summary: CoverageMetrics
|
|
188
|
+
files: CoverageFile[]
|
|
189
|
+
reportArtifactIds: string[]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface BrowserEnvironmentInfo {
|
|
193
|
+
name: string
|
|
194
|
+
version: string
|
|
195
|
+
headless: boolean
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export interface TestEnvironmentInfo {
|
|
199
|
+
kind: 'dom' | 'browser'
|
|
200
|
+
react: string | null
|
|
201
|
+
reactDom: string | null
|
|
202
|
+
v8: string
|
|
203
|
+
browser: BrowserEnvironmentInfo | null
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type TestMetadataValue =
|
|
207
|
+
| null
|
|
208
|
+
| boolean
|
|
209
|
+
| number
|
|
210
|
+
| string
|
|
211
|
+
| TestMetadataValue[]
|
|
212
|
+
| { [key: string]: TestMetadataValue }
|
|
213
|
+
|
|
214
|
+
export interface TestArtifact {
|
|
215
|
+
id: string
|
|
216
|
+
kind: string
|
|
217
|
+
path: string
|
|
218
|
+
suiteId: string | null
|
|
219
|
+
testId: string | null
|
|
220
|
+
metadata: Record<string, TestMetadataValue>
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface TestDiagnostic {
|
|
224
|
+
severity: 'error' | 'warning' | 'note' | 'help'
|
|
225
|
+
code: string
|
|
226
|
+
message: string
|
|
227
|
+
path: string | null
|
|
228
|
+
location: TestLocation | null
|
|
229
|
+
notes?: string[]
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface TestLeak {
|
|
233
|
+
kind: 'timer' | 'listener' | 'task' | 'socket' | 'network' | 'other'
|
|
234
|
+
description: string
|
|
235
|
+
location: TestLocation | null
|
|
236
|
+
stack: string | null
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface TestSuiteResult {
|
|
240
|
+
id: string
|
|
241
|
+
path: string
|
|
242
|
+
name: string | null
|
|
243
|
+
project: string | null
|
|
244
|
+
environment: TestEnvironmentInfo | null
|
|
245
|
+
status: TestSuiteStatus
|
|
246
|
+
durationMs: number
|
|
247
|
+
tests: TestCaseResult[]
|
|
248
|
+
failures: TestFailure[]
|
|
249
|
+
snapshot: SnapshotSummary | null
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface TestStatusCounts {
|
|
253
|
+
total: number
|
|
254
|
+
passed: number
|
|
255
|
+
failed: number
|
|
256
|
+
skipped: number
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface TestCaseStatusCounts extends TestStatusCounts {
|
|
260
|
+
todo: number
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface TestRunCounts {
|
|
264
|
+
suites: TestStatusCounts
|
|
265
|
+
tests: TestCaseStatusCounts
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface TestRunResult {
|
|
269
|
+
schemaVersion: 'wake.test.v1'
|
|
270
|
+
runId: string
|
|
271
|
+
success: boolean
|
|
272
|
+
seed: string
|
|
273
|
+
durationMs: number
|
|
274
|
+
terminationReason: TestTerminationReason
|
|
275
|
+
environment: TestEnvironmentInfo
|
|
276
|
+
suites: TestSuiteResult[]
|
|
277
|
+
counts: TestRunCounts
|
|
278
|
+
snapshot: SnapshotSummary
|
|
279
|
+
coverage: CoverageResult | null
|
|
280
|
+
leaks: TestLeak[]
|
|
281
|
+
artifacts: TestArtifact[]
|
|
282
|
+
diagnostics: TestDiagnostic[]
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface TestRunStartEvent {
|
|
286
|
+
runId: string
|
|
287
|
+
watching: boolean
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export interface TestCaseResultEvent {
|
|
291
|
+
runId: string
|
|
292
|
+
suiteId: string
|
|
293
|
+
result: TestCaseResult
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface TestSuiteResultEvent {
|
|
297
|
+
runId: string
|
|
298
|
+
result: TestSuiteResult
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export class TestContext extends EventEmitter {
|
|
302
|
+
private constructor()
|
|
303
|
+
readonly watching: boolean
|
|
304
|
+
readonly closed: boolean
|
|
305
|
+
run(): Promise<TestRunResult>
|
|
306
|
+
startWatch(): this
|
|
307
|
+
stopWatch(): this
|
|
308
|
+
close(): Promise<void>
|
|
309
|
+
[Symbol.asyncDispose](): Promise<void>
|
|
310
|
+
on(event: 'runStart', listener: (event: TestRunStartEvent) => void): this
|
|
311
|
+
on(event: 'testCaseResult', listener: (event: TestCaseResultEvent) => void): this
|
|
312
|
+
on(event: 'suiteResult', listener: (event: TestSuiteResultEvent) => void): this
|
|
313
|
+
on(event: 'runComplete', listener: (result: TestRunResult) => void): this
|
|
314
|
+
on(event: 'diagnostic', listener: (diagnostic: TestDiagnostic) => void): this
|
|
315
|
+
on(event: 'closed', listener: () => void): this
|
|
316
|
+
}
|
|
317
|
+
|
|
69
318
|
export type BundlePlatform = 'browser' | 'node'
|
|
70
319
|
export type BundleFormat = 'iife' | 'cjs'
|
|
71
320
|
export type NodeTarget = `node${number}` | `node${number}.${number}`
|
|
@@ -272,6 +521,8 @@ export function buildLibrary(options?: LibraryBuildOptions): Promise<LibraryBuil
|
|
|
272
521
|
export function generateCssToken(options?: GenerateCssTokenOptions): Promise<GenerateCssTokenResult>
|
|
273
522
|
export function generateDocgen(options?: GenerateDocgenOptions): Promise<GenerateDocgenResult>
|
|
274
523
|
export function createBuildContext(options?: BuildOptions): Promise<BuildContext>
|
|
524
|
+
export function runTests(options?: TestOptions & { signal?: AbortSignal }): Promise<TestRunResult>
|
|
525
|
+
export function createTestContext(options?: TestOptions): Promise<TestContext>
|
|
275
526
|
export function startDevServer(options?: DevServerOptions): Promise<DevServer>
|
|
276
527
|
export function buildDocs(options?: DocsBuildOptions): Promise<DocsBuildResult>
|
|
277
528
|
export function startDocsDevServer(options?: DocsDevServerOptions): Promise<DevServer>
|
|
@@ -279,6 +530,7 @@ export function startDocsDevServer(options?: DocsDevServerOptions): Promise<DevS
|
|
|
279
530
|
declare const wake: {
|
|
280
531
|
BuildContext: typeof BuildContext
|
|
281
532
|
DevServer: typeof DevServer
|
|
533
|
+
TestContext: typeof TestContext
|
|
282
534
|
WakeError: typeof WakeError
|
|
283
535
|
build: typeof build
|
|
284
536
|
buildLibrary: typeof buildLibrary
|
|
@@ -287,6 +539,8 @@ declare const wake: {
|
|
|
287
539
|
generateCssToken: typeof generateCssToken
|
|
288
540
|
generateDocgen: typeof generateDocgen
|
|
289
541
|
createBuildContext: typeof createBuildContext
|
|
542
|
+
runTests: typeof runTests
|
|
543
|
+
createTestContext: typeof createTestContext
|
|
290
544
|
startDevServer: typeof startDevServer
|
|
291
545
|
startDocsDevServer: typeof startDocsDevServer
|
|
292
546
|
version: typeof version
|
package/index.mjs
CHANGED
|
@@ -3,14 +3,17 @@ import api from './index.cjs'
|
|
|
3
3
|
export const {
|
|
4
4
|
BuildContext,
|
|
5
5
|
DevServer,
|
|
6
|
+
TestContext,
|
|
6
7
|
WakeError,
|
|
7
8
|
build,
|
|
8
9
|
buildLibrary,
|
|
9
10
|
buildDocs,
|
|
10
11
|
bundle,
|
|
12
|
+
runTests,
|
|
11
13
|
generateCssToken,
|
|
12
14
|
generateDocgen,
|
|
13
15
|
createBuildContext,
|
|
16
|
+
createTestContext,
|
|
14
17
|
startDevServer,
|
|
15
18
|
startDocsDevServer,
|
|
16
19
|
version,
|
package/loader.cjs
CHANGED
|
@@ -17,9 +17,25 @@ function unsupported(message, cause) {
|
|
|
17
17
|
return error
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function attachTestHost(native, nativePath) {
|
|
21
|
+
const hostPath = process.env.WAKE_TEST_HOST_PATH || path.join(
|
|
22
|
+
path.dirname(nativePath),
|
|
23
|
+
'test-host',
|
|
24
|
+
process.platform === 'win32' ? 'wake-test-host.exe' : 'wake-test-host',
|
|
25
|
+
)
|
|
26
|
+
Object.defineProperty(native, '__wakeTestHostPath', {
|
|
27
|
+
configurable: false,
|
|
28
|
+
enumerable: false,
|
|
29
|
+
writable: false,
|
|
30
|
+
value: hostPath,
|
|
31
|
+
})
|
|
32
|
+
return native
|
|
33
|
+
}
|
|
34
|
+
|
|
20
35
|
function loadNative() {
|
|
21
36
|
if (process.env.WAKE_NATIVE_PATH) {
|
|
22
|
-
|
|
37
|
+
const nativePath = path.resolve(process.env.WAKE_NATIVE_PATH)
|
|
38
|
+
return attachTestHost(require(nativePath), nativePath)
|
|
23
39
|
}
|
|
24
40
|
|
|
25
41
|
const key = `${process.platform}-${process.arch}`
|
|
@@ -41,7 +57,8 @@ function loadNative() {
|
|
|
41
57
|
}
|
|
42
58
|
|
|
43
59
|
try {
|
|
44
|
-
|
|
60
|
+
const nativePath = require.resolve(packageName)
|
|
61
|
+
return attachTestHost(require(nativePath), nativePath)
|
|
45
62
|
} catch (cause) {
|
|
46
63
|
throw unsupported(
|
|
47
64
|
`Unable to load ${packageName} for ${process.platform}/${process.arch}. ` +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crab-dev/wake",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "Wake native web build tools for Node.js",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -22,6 +22,16 @@
|
|
|
22
22
|
"import": "./experimental.mjs",
|
|
23
23
|
"require": "./experimental.cjs"
|
|
24
24
|
},
|
|
25
|
+
"./test": {
|
|
26
|
+
"types": "./test.d.ts",
|
|
27
|
+
"import": "./test.mjs",
|
|
28
|
+
"require": "./test.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./test/react": {
|
|
31
|
+
"types": "./test-react.d.ts",
|
|
32
|
+
"import": "./test-react.mjs",
|
|
33
|
+
"require": "./test-react.cjs"
|
|
34
|
+
},
|
|
25
35
|
"./internal/components-runtime": {
|
|
26
36
|
"types": "./internal/components-runtime.d.ts",
|
|
27
37
|
"import": "./internal/components-runtime.mjs"
|
|
@@ -41,6 +51,12 @@
|
|
|
41
51
|
"*.mjs",
|
|
42
52
|
"index.d.ts",
|
|
43
53
|
"experimental.d.ts",
|
|
54
|
+
"test.cjs",
|
|
55
|
+
"test.mjs",
|
|
56
|
+
"test.d.ts",
|
|
57
|
+
"test-react.cjs",
|
|
58
|
+
"test-react.mjs",
|
|
59
|
+
"test-react.d.ts",
|
|
44
60
|
"README.md",
|
|
45
61
|
"CHANGELOG.md",
|
|
46
62
|
"LICENSE-MIT",
|
|
@@ -50,7 +66,7 @@
|
|
|
50
66
|
"node": ">=22.14 <27"
|
|
51
67
|
},
|
|
52
68
|
"dependencies": {
|
|
53
|
-
"@crab-dev/css": "0.1.
|
|
69
|
+
"@crab-dev/css": "0.1.22",
|
|
54
70
|
"@crab-dev/rc-alert": "^0.0.2",
|
|
55
71
|
"@crab-dev/rc-button": "^0.0.2",
|
|
56
72
|
"@crab-dev/rc-dialog": "^0.0.2",
|
|
@@ -71,15 +87,15 @@
|
|
|
71
87
|
"string-width": "8.2.2"
|
|
72
88
|
},
|
|
73
89
|
"peerDependencies": {
|
|
74
|
-
"react": "
|
|
75
|
-
"react-dom": "
|
|
90
|
+
"react": ">=19.2.8 <19.3.0",
|
|
91
|
+
"react-dom": ">=19.2.8 <19.3.0"
|
|
76
92
|
},
|
|
77
93
|
"optionalDependencies": {
|
|
78
|
-
"@crab-dev/wake-darwin-arm64": "0.1.
|
|
79
|
-
"@crab-dev/wake-darwin-x64": "0.1.
|
|
80
|
-
"@crab-dev/wake-linux-arm64-gnu": "0.1.
|
|
81
|
-
"@crab-dev/wake-linux-x64-gnu": "0.1.
|
|
82
|
-
"@crab-dev/wake-win32-x64-msvc": "0.1.
|
|
94
|
+
"@crab-dev/wake-darwin-arm64": "0.1.22",
|
|
95
|
+
"@crab-dev/wake-darwin-x64": "0.1.22",
|
|
96
|
+
"@crab-dev/wake-linux-arm64-gnu": "0.1.22",
|
|
97
|
+
"@crab-dev/wake-linux-x64-gnu": "0.1.22",
|
|
98
|
+
"@crab-dev/wake-win32-x64-msvc": "0.1.22"
|
|
83
99
|
},
|
|
84
100
|
"publishConfig": {
|
|
85
101
|
"access": "public",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const contexts = new WeakMap()
|
|
4
|
+
|
|
5
|
+
function registerTestContext(context, handle) {
|
|
6
|
+
contexts.set(context, { handle, fatalError: undefined })
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function sendTestWatchControl(context, control) {
|
|
10
|
+
const record = contexts.get(context)
|
|
11
|
+
if (!record) throw new TypeError('Expected a Wake TestContext')
|
|
12
|
+
record.handle.watchControl(JSON.stringify(control))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function setTestContextFatalError(context, error) {
|
|
16
|
+
const record = contexts.get(context)
|
|
17
|
+
if (!record) throw new TypeError('Expected a Wake TestContext')
|
|
18
|
+
record.fatalError = error
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getTestContextFatalError(context) {
|
|
22
|
+
return contexts.get(context)?.fatalError
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
getTestContextFatalError,
|
|
27
|
+
registerTestContext,
|
|
28
|
+
sendTestWatchControl,
|
|
29
|
+
setTestContextFatalError,
|
|
30
|
+
}
|