@solidrt/test 0.0.73 → 0.0.74
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/AGENTS.md +8 -1
- package/package.json +3 -3
- package/src/index.ts +40 -9
package/AGENTS.md
CHANGED
|
@@ -59,13 +59,20 @@ agents/testing.md.
|
|
|
59
59
|
app registered with `registerDebug` and returns its value: the way to
|
|
60
60
|
put a loaded app into a state its UI reaches slowly. A `gamepad` event
|
|
61
61
|
in `app.input` seats and drives a synthetic pad, as `send_input` does.
|
|
62
|
-
- `await app.camera({ width, height,
|
|
62
|
+
- `await app.camera({ width, height, data })` makes an RGBA8 image (a
|
|
63
63
|
`decodeImage` result, or pixels the test builds) what the camera sees:
|
|
64
64
|
every camera the app opens shows it, with no device and no prompt, and
|
|
65
65
|
an open one shows it from the next frame. Call it before the app opens
|
|
66
66
|
its camera; call it again to show another image. A QR code in it is
|
|
67
67
|
decoded as from a real camera, so `settle()` after the open and read
|
|
68
68
|
the app's barcode state.
|
|
69
|
+
- `await app.microphone({ sampleRate, samples })` makes a mono float clip
|
|
70
|
+
what the microphone hears: every microphone the app opens at that rate
|
|
71
|
+
holds it from the open, with no device and no prompt (`settle()` after
|
|
72
|
+
the mount, the open resolves through the engine), and an open one hears it now
|
|
73
|
+
(a runtime module reading the session included). Call it before the
|
|
74
|
+
app opens its microphone; call it again to say more. An open at another
|
|
75
|
+
rate fails naming both rates.
|
|
69
76
|
- Past a node's record: `locator.outline()` is the subtree as an outline
|
|
70
77
|
(kind, label, text, box per line, no ids) to pin a layout or print it;
|
|
71
78
|
`locator.pixel(x, y)` is `[r, g, b, a]` at a point of the node and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidrt/test",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.74",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"funding": "https://github.com/sponsors/wellawaretech",
|
|
6
6
|
"author": "Antoine van Wel",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"AGENTS.md"
|
|
15
15
|
],
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@solidrt/flux-types": "0.0.
|
|
17
|
+
"@solidrt/flux-types": "0.0.74"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@solidrt/core": "0.0.
|
|
20
|
+
"@solidrt/core": "0.0.74"
|
|
21
21
|
}
|
|
22
22
|
}
|
package/src/index.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { test as register, expect } from "flux:test"
|
|
18
18
|
import * as gui from "flux:test/gui"
|
|
19
|
-
import { camera as installCamera, capture, debug, frame as stepFrame, frameRate, inputPlan, inputStep, link, painted as paintFrame, setFrameRate, settle, time, windowReady } from "sol:test"
|
|
19
|
+
import { camera as installCamera, capture, debug, frame as stepFrame, frameRate, inputPlan, inputStep, link, microphone as installMicrophone, painted as paintFrame, setFrameRate, settle, time, windowReady } from "sol:test"
|
|
20
20
|
import { createElement, insert, render } from "@solidrt/core"
|
|
21
21
|
|
|
22
22
|
export { expect }
|
|
@@ -158,11 +158,18 @@ export interface PointerOptions {
|
|
|
158
158
|
meta?: boolean
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
/** An RGBA8 image, tightly packed rows top to bottom:
|
|
161
|
+
/** An RGBA8 image, tightly packed rows top to bottom: the shape `decodeImage` returns (and the web's `ImageData`). */
|
|
162
162
|
export interface CameraImage {
|
|
163
163
|
width: number
|
|
164
164
|
height: number
|
|
165
|
-
|
|
165
|
+
data: Uint8Array
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** A mono clip: float samples at a sample rate, the shape `read()` of a microphone session delivers. */
|
|
169
|
+
export interface MicrophoneClip {
|
|
170
|
+
/** Hz; the rate the app opens its microphone at. */
|
|
171
|
+
sampleRate: number
|
|
172
|
+
samples: Float32Array
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
/** The app under test, as a test's function receives it. */
|
|
@@ -206,7 +213,7 @@ export interface TestApp {
|
|
|
206
213
|
* it; call it again to show the app another image. A QR code in the
|
|
207
214
|
* image is decoded like one in front of a real camera: `settle()` after
|
|
208
215
|
* the open and the app's barcode handler has run. Pass a `decodeImage`
|
|
209
|
-
* result, or
|
|
216
|
+
* result, or an image the test builds.
|
|
210
217
|
*
|
|
211
218
|
* @example
|
|
212
219
|
* await app.camera(decodeImage(png))
|
|
@@ -215,6 +222,23 @@ export interface TestApp {
|
|
|
215
222
|
* expect(cam.barcode()?.data).toBe("solidrt")
|
|
216
223
|
*/
|
|
217
224
|
camera(image: CameraImage): Promise<void>
|
|
225
|
+
/**
|
|
226
|
+
* Makes `clip` what the microphone hears: every microphone the app opens
|
|
227
|
+
* at the clip's rate from now on holds it from the open (a
|
|
228
|
+
* `createMicrophone` or `open` resolves at once, no device, no prompt), and a
|
|
229
|
+
* microphone already open hears it now, so a module reading the session
|
|
230
|
+
* on its own thread gets it too. Call it before `mount` or `load` so the
|
|
231
|
+
* app's own open finds a microphone; call it again to say something else
|
|
232
|
+
* to an open one. An open at another rate than the clip's fails naming
|
|
233
|
+
* both rates. Results a module or recognizer produces land through the
|
|
234
|
+
* engine: `settle()` after the install.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* await app.microphone({ sampleRate: 16000, samples: tone })
|
|
238
|
+
* let mic = createMicrophone()
|
|
239
|
+
* expect(mic.read()).toEqual(tone)
|
|
240
|
+
*/
|
|
241
|
+
microphone(clip: MicrophoneClip): Promise<void>
|
|
218
242
|
/**
|
|
219
243
|
* Calls a debug command the app registered (`registerDebug` of
|
|
220
244
|
* `sol:dev`), runs a frame, and returns what the command returned. The
|
|
@@ -522,14 +546,21 @@ let app: TestApp = {
|
|
|
522
546
|
await app.frame()
|
|
523
547
|
},
|
|
524
548
|
async camera(image) {
|
|
525
|
-
let ok = image !== null && typeof image === "object" && image.
|
|
526
|
-
if (!ok) throw new TypeError("camera: pass { width, height,
|
|
527
|
-
let { width, height,
|
|
549
|
+
let ok = image !== null && typeof image === "object" && image.data instanceof Uint8Array
|
|
550
|
+
if (!ok) throw new TypeError("camera: pass { width, height, data }, with data a Uint8Array of RGBA8 (what decodeImage returns)")
|
|
551
|
+
let { width, height, data } = image
|
|
528
552
|
if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) throw new TypeError(`camera: the size must be positive integers, got ${width} x ${height}`)
|
|
529
|
-
if (
|
|
530
|
-
installCamera(width, height,
|
|
553
|
+
if (data.length !== width * height * RGBA) throw new TypeError(`camera: ${width} x ${height} RGBA8 is ${width * height * RGBA} bytes, got ${data.length}`)
|
|
554
|
+
installCamera(width, height, data)
|
|
531
555
|
await app.frame()
|
|
532
556
|
},
|
|
557
|
+
async microphone(clip) {
|
|
558
|
+
let ok = clip !== null && typeof clip === "object" && clip.samples instanceof Float32Array
|
|
559
|
+
if (!ok) throw new TypeError("microphone: pass { sampleRate, samples }, with samples a Float32Array of mono samples")
|
|
560
|
+
let { sampleRate, samples } = clip
|
|
561
|
+
if (!Number.isInteger(sampleRate) || sampleRate <= 0) throw new TypeError(`microphone: the sample rate must be a positive integer, got ${sampleRate}`)
|
|
562
|
+
installMicrophone(sampleRate, samples)
|
|
563
|
+
},
|
|
533
564
|
async debug(name, args) {
|
|
534
565
|
let result = debug(name, args === undefined ? null : JSON.stringify(args))
|
|
535
566
|
await app.frame()
|