@wardic/test 1.0.0-rc.3 → 1.0.0-rc.5
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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/layer.d.ts +5 -4
- package/dist/layer.d.ts.map +1 -1
- package/dist/layer.js +2 -2
- package/dist/layer.js.map +1 -1
- package/dist/probe.d.ts +8 -6
- package/dist/probe.d.ts.map +1 -1
- package/dist/probe.js +11 -11
- package/dist/probe.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -1
- package/src/layer.ts +4 -2
- package/src/probe.ts +26 -20
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Nothing is drawn on a page: an app's components are tested with `DomLive`
|
|
8
8
|
* under the test runner's fake timers, as https://wardic.dev/guides/testing shows.
|
|
9
9
|
*/
|
|
10
|
-
export declare const VERSION = "1.0.0-rc.
|
|
10
|
+
export declare const VERSION = "1.0.0-rc.5";
|
|
11
11
|
export * as TestClock from "./clock.ts";
|
|
12
12
|
export * as TestRenderer from "./renderer.ts";
|
|
13
13
|
export * as TestProbe from "./probe.ts";
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* under the test runner's fake timers, as https://wardic.dev/guides/testing shows.
|
|
9
9
|
*/
|
|
10
10
|
// The testing guide: #558.
|
|
11
|
-
export const VERSION = "1.0.0-rc.
|
|
11
|
+
export const VERSION = "1.0.0-rc.5";
|
|
12
12
|
export * as TestClock from "./clock.js";
|
|
13
13
|
export * as TestRenderer from "./renderer.js";
|
|
14
14
|
export * as TestProbe from "./probe.js";
|
package/dist/layer.d.ts
CHANGED
|
@@ -8,12 +8,13 @@ import type * as Probe from "@wardic/core/Probe";
|
|
|
8
8
|
import * as ReducedMotion from "@wardic/core/ReducedMotion";
|
|
9
9
|
import * as RefreshFrameSource from "@wardic/core/RefreshFrameSource";
|
|
10
10
|
import type * as Renderer from "@wardic/core/Renderer";
|
|
11
|
+
import type * as ScrollSource from "@wardic/core/ScrollSource";
|
|
11
12
|
import * as Layer from "effect/Layer";
|
|
12
13
|
import { AtomRegistry } from "effect/reactivity";
|
|
13
14
|
/**
|
|
14
15
|
* The full headless environment: deterministic Clock (driven by `frames`), a Refresh frame
|
|
15
|
-
* source that never calls back, recording Renderer, static Probe
|
|
16
|
-
* interpolator registry, a fresh AtomRegistry for reading Probe atoms
|
|
16
|
+
* source that never calls back, recording Renderer, static Probe and ScrollSource, silent
|
|
17
|
+
* InputSource, core's real interpolator registry, a fresh AtomRegistry for reading Probe atoms
|
|
17
18
|
* (`viewport`, `prefersReducedMotion`), and a fresh Drag activity, so one test's
|
|
18
19
|
* drag never blocks another's hover or press, and core's Frame loop over that
|
|
19
20
|
* Clock. Provide this in place of `DomLive` to test animation code without a
|
|
@@ -21,7 +22,7 @@ import { AtomRegistry } from "effect/reactivity";
|
|
|
21
22
|
* app's components are tested with `DomLive` under the test runner's fake timers instead
|
|
22
23
|
* (https://wardic.dev/guides/testing).
|
|
23
24
|
*/
|
|
24
|
-
export declare const testLayer: (frames?: ReadonlyArray<number>) => Layer.Layer<Clock.Clock | RefreshFrameSource.RefreshFrameSource | FrameLoop.FrameLoop | Renderer.Renderer | Probe.Probe | InputSource.InputSource | InterpolatorRegistry.InterpolatorRegistry | ReducedMotion.PositionalKeys | DefaultTransition.DefaultTransition | Announcer.Announcer | AtomRegistry.AtomRegistry>;
|
|
25
|
+
export declare const testLayer: (frames?: ReadonlyArray<number>) => Layer.Layer<Clock.Clock | RefreshFrameSource.RefreshFrameSource | FrameLoop.FrameLoop | Renderer.Renderer | Probe.Probe | ScrollSource.ScrollSource | InputSource.InputSource | InterpolatorRegistry.InterpolatorRegistry | ReducedMotion.PositionalKeys | DefaultTransition.DefaultTransition | Announcer.Announcer | AtomRegistry.AtomRegistry>;
|
|
25
26
|
/** `testLayer()` with an empty clock — for tests that drive their own frames. It never ticks on its own. */
|
|
26
|
-
export declare const TestLive: Layer.Layer<Announcer.Announcer | AtomRegistry.AtomRegistry | Clock.Clock | DefaultTransition.DefaultTransition | FrameLoop.FrameLoop | InputSource.InputSource | InterpolatorRegistry.InterpolatorRegistry | ReducedMotion.PositionalKeys | Probe.Probe | RefreshFrameSource.RefreshFrameSource | Renderer.Renderer, never, never>;
|
|
27
|
+
export declare const TestLive: Layer.Layer<Announcer.Announcer | AtomRegistry.AtomRegistry | Clock.Clock | DefaultTransition.DefaultTransition | FrameLoop.FrameLoop | InputSource.InputSource | InterpolatorRegistry.InterpolatorRegistry | ReducedMotion.PositionalKeys | Probe.Probe | RefreshFrameSource.RefreshFrameSource | Renderer.Renderer | ScrollSource.ScrollSource, never, never>;
|
|
27
28
|
//# sourceMappingURL=layer.d.ts.map
|
package/dist/layer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["../src/layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,KAAK,KAAK,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAA;AAEnE,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,KAAK,WAAW,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,oBAAoB,MAAM,mCAAmC,CAAA;AAEzE,OAAO,KAAK,KAAK,KAAK,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,kBAAkB,MAAM,iCAAiC,CAAA;AACrE,OAAO,KAAK,KAAK,QAAQ,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["../src/layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,KAAK,KAAK,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAA;AAEnE,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AACnD,OAAO,KAAK,KAAK,WAAW,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,oBAAoB,MAAM,mCAAmC,CAAA;AAEzE,OAAO,KAAK,KAAK,KAAK,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,kBAAkB,MAAM,iCAAiC,CAAA;AACrE,OAAO,KAAK,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,KAAK,YAAY,MAAM,2BAA2B,CAAA;AAE9D,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAahD;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,SAAS,YACZ,aAAa,CAAC,MAAM,CAAC,KAC5B,KAAK,CAAC,KAAK,CACV,KAAK,CAAC,KAAK,GACX,kBAAkB,CAAC,kBAAkB,GACrC,SAAS,CAAC,SAAS,GACnB,QAAQ,CAAC,QAAQ,GACjB,KAAK,CAAC,KAAK,GACX,YAAY,CAAC,YAAY,GACzB,WAAW,CAAC,WAAW,GACvB,oBAAoB,CAAC,oBAAoB,GACzC,aAAa,CAAC,cAAc,GAC5B,iBAAiB,CAAC,iBAAiB,GACnC,SAAS,CAAC,SAAS,GACnB,YAAY,CAAC,YAAY,CAsB1B,CAAA;AAEH,4GAA4G;AAC5G,eAAO,MAAM,QAAQ,iWAAc,CAAA"}
|
package/dist/layer.js
CHANGED
|
@@ -21,8 +21,8 @@ import * as TestRenderer from "./renderer.js";
|
|
|
21
21
|
const stillFrames = { requestFrame: constUndefined, cancelFrame: constVoid };
|
|
22
22
|
/**
|
|
23
23
|
* The full headless environment: deterministic Clock (driven by `frames`), a Refresh frame
|
|
24
|
-
* source that never calls back, recording Renderer, static Probe
|
|
25
|
-
* interpolator registry, a fresh AtomRegistry for reading Probe atoms
|
|
24
|
+
* source that never calls back, recording Renderer, static Probe and ScrollSource, silent
|
|
25
|
+
* InputSource, core's real interpolator registry, a fresh AtomRegistry for reading Probe atoms
|
|
26
26
|
* (`viewport`, `prefersReducedMotion`), and a fresh Drag activity, so one test's
|
|
27
27
|
* drag never blocks another's hover or press, and core's Frame loop over that
|
|
28
28
|
* Clock. Provide this in place of `DomLive` to test animation code without a
|
package/dist/layer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer.js","sourceRoot":"","sources":["../src/layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AAEnD,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,YAAY,MAAM,2BAA2B,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AAEnD,OAAO,KAAK,oBAAoB,MAAM,mCAAmC,CAAA;AACzE,OAAO,KAAK,WAAW,MAAM,0BAA0B,CAAA;AAEvD,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,kBAAkB,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"layer.js","sourceRoot":"","sources":["../src/layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AAEnD,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,YAAY,MAAM,2BAA2B,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAA;AAEnD,OAAO,KAAK,oBAAoB,MAAM,mCAAmC,CAAA;AACzE,OAAO,KAAK,WAAW,MAAM,0BAA0B,CAAA;AAEvD,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,kBAAkB,MAAM,iCAAiC,CAAA;AAGrE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,SAAS,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,eAAe,CAAA;AAE7C;;;;GAIG;AACH,MAAM,WAAW,GAA6B,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,CAAA;AAEtG;;;;;;;;;;GAUG;AACH,kFAAkF;AAClF,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,MAAM,GAA0B,EAAE,EAclC,EAAE,CACF,SAAS,CAAC,KAAK,CAAC,IAAI,CAClB,KAAK,CAAC,YAAY,CAChB,KAAK,CAAC,QAAQ,CACZ,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EACvB,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,EACrC,YAAY,CAAC,KAAK,EAClB,SAAS,CAAC,KAAK,EAAE,EACjB,SAAS,CAAC,KAAK,EAAE,EACjB,oBAAoB,CAAC,KAAK;AAC1B,0EAA0E;AAC1E,aAAa,CAAC,cAAc;AAC5B,gFAAgF;AAChF,iBAAiB,CAAC,cAAc;AAChC,wDAAwD;AACxD,SAAS,CAAC,WAAW,EACrB,YAAY,CAAC,KAAK,EAClB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,EACxD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,CACtD,CACF,CACF,CAAA;AAEH,4GAA4G;AAC5G,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAA"}
|
package/dist/probe.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Probe from "@wardic/core/Probe";
|
|
2
|
+
import * as ScrollSource from "@wardic/core/ScrollSource";
|
|
2
3
|
import * as Effect from "effect/Effect";
|
|
3
4
|
import * as Layer from "effect/Layer";
|
|
4
5
|
import { AtomRegistry } from "effect/reactivity";
|
|
@@ -12,8 +13,8 @@ export interface Options {
|
|
|
12
13
|
readonly prefersReducedMotion?: boolean;
|
|
13
14
|
/** Whether the Environment is shown: `true` when left out. */
|
|
14
15
|
readonly visible?: boolean;
|
|
15
|
-
/** Every container's scroll, as `
|
|
16
|
-
readonly scroll?:
|
|
16
|
+
/** Every container's scroll, as the `ScrollSource` gives it: a page that doesn't scroll when left out. */
|
|
17
|
+
readonly scroll?: ScrollSource.Scroll;
|
|
17
18
|
/**
|
|
18
19
|
* Script of intersection (in-view) booleans replayed by `observeIntersection`, an **Input feed**
|
|
19
20
|
* that ends after it. Mirrors the InputSource test harness: omitted (or empty) means it
|
|
@@ -24,9 +25,10 @@ export interface Options {
|
|
|
24
25
|
/**
|
|
25
26
|
* A static Probe: fixed bounds/viewport. `observeIntersection` replays the
|
|
26
27
|
* optional `intersection` script to each subscriber (empty by default, so it
|
|
27
|
-
* emits nothing); `observeResize` stays empty.
|
|
28
|
+
* emits nothing); `observeResize` stays empty. With it, a `ScrollSource`
|
|
29
|
+
* whose every container reads `scroll`, as the Probe's `scroll` did until #518.
|
|
28
30
|
*/
|
|
29
|
-
export declare const layer: (options?: Options) => Layer.Layer<Probe.Probe>;
|
|
31
|
+
export declare const layer: (options?: Options) => Layer.Layer<Probe.Probe | ScrollSource.ScrollSource>;
|
|
30
32
|
/**
|
|
31
33
|
* A push-based Probe for tests that need to interleave intersection
|
|
32
34
|
* (in-view/out-of-view) transitions with other effects on their own schedule —
|
|
@@ -39,8 +41,8 @@ export declare const layer: (options?: Options) => Layer.Layer<Probe.Probe>;
|
|
|
39
41
|
* measure/viewport/prefersReducedMotion/observeResize behave as in {@link layer}.
|
|
40
42
|
*/
|
|
41
43
|
export declare const pushable: (options?: Options) => Effect.Effect<{
|
|
42
|
-
readonly layer: Layer.Layer<Probe.Probe>;
|
|
44
|
+
readonly layer: Layer.Layer<Probe.Probe | ScrollSource.ScrollSource>;
|
|
43
45
|
readonly pushIntersection: (inView: boolean) => Effect.Effect<void>;
|
|
44
|
-
readonly pushScroll: (scroll:
|
|
46
|
+
readonly pushScroll: (scroll: ScrollSource.Scroll) => Effect.Effect<void, never, AtomRegistry.AtomRegistry>;
|
|
45
47
|
}>;
|
|
46
48
|
//# sourceMappingURL=probe.d.ts.map
|
package/dist/probe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,oBAAoB,CAAA;AAC3C,OAAO,KAAK,YAAY,MAAM,2BAA2B,CAAA;AAEzD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,EAAQ,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAWtD,yCAAyC;AAGzC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACvE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;IACvC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,0GAA0G;IAC1G,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,MAAM,CAAA;IACrC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CAC/C;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,aAAa,OAAO,KAAQ,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,YAAY,CAAC,YAAY,CAShG,CAAA;AAeD;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,QAAQ,aAAa,OAAO,KAAQ,MAAM,CAAC,MAAM,CAAC;IAC7D,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;IACpE,QAAQ,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACnE,QAAQ,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,YAAY,CAAC,CAAA;CAC5G,CAUG,CAAA"}
|
package/dist/probe.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Probe from "@wardic/core/Probe";
|
|
2
|
+
import * as ScrollSource from "@wardic/core/ScrollSource";
|
|
2
3
|
import * as Arr from "effect/Array";
|
|
3
4
|
import * as Effect from "effect/Effect";
|
|
4
5
|
import * as Layer from "effect/Layer";
|
|
@@ -14,27 +15,26 @@ const toIntersection = (intersecting) => ({ intersecting });
|
|
|
14
15
|
/**
|
|
15
16
|
* A static Probe: fixed bounds/viewport. `observeIntersection` replays the
|
|
16
17
|
* optional `intersection` script to each subscriber (empty by default, so it
|
|
17
|
-
* emits nothing); `observeResize` stays empty.
|
|
18
|
+
* emits nothing); `observeResize` stays empty. With it, a `ScrollSource`
|
|
19
|
+
* whose every container reads `scroll`, as the Probe's `scroll` did until #518.
|
|
18
20
|
*/
|
|
19
21
|
export const layer = (options = {}) => {
|
|
20
22
|
const { intersection = [], scroll = STILL_SCROLL } = options;
|
|
21
|
-
return Layer.succeed(Probe.Probe, {
|
|
22
|
-
...fixed(options
|
|
23
|
+
return Layer.mergeAll(Layer.succeed(Probe.Probe, {
|
|
24
|
+
...fixed(options),
|
|
23
25
|
observeIntersection: () => Feeds.script(Arr.map(intersection, toIntersection)),
|
|
24
|
-
});
|
|
26
|
+
}), scrollLayer(Atom.make(scroll)));
|
|
25
27
|
};
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
* and one scroll Atom for every container, target and offset (#234).
|
|
29
|
-
*/
|
|
30
|
-
const fixed = ({ bounds = ZERO_BOUNDS, viewport = VIEWPORT, prefersReducedMotion = false, visible = true }, scroll) => ({
|
|
28
|
+
/** Both Probes' fixed part: the bounds, the viewport, the preference and the page's visibility, each defaulted, and no resizes. */
|
|
29
|
+
const fixed = ({ bounds = ZERO_BOUNDS, viewport = VIEWPORT, prefersReducedMotion = false, visible = true }) => ({
|
|
31
30
|
measure: () => Effect.sync(() => bounds),
|
|
32
31
|
viewport: Atom.make(viewport),
|
|
33
32
|
prefersReducedMotion: Atom.make(prefersReducedMotion),
|
|
34
33
|
visible: Atom.make(visible),
|
|
35
|
-
scroll: () => Effect.succeed(scroll),
|
|
36
34
|
observeResize: () => Stream.empty,
|
|
37
35
|
});
|
|
36
|
+
/** One scroll Atom for every container, target and offset (#234). */
|
|
37
|
+
const scrollLayer = (scroll) => Layer.succeed(ScrollSource.ScrollSource, { scroll: () => Effect.succeed(scroll) });
|
|
38
38
|
/**
|
|
39
39
|
* A push-based Probe for tests that need to interleave intersection
|
|
40
40
|
* (in-view/out-of-view) transitions with other effects on their own schedule —
|
|
@@ -52,7 +52,7 @@ export const pushable = (options = {}) => Effect.sync(() => {
|
|
|
52
52
|
const { scroll = STILL_SCROLL } = options;
|
|
53
53
|
const scrollAtom = Atom.make(scroll);
|
|
54
54
|
return {
|
|
55
|
-
layer: Layer.succeed(Probe.Probe, { ...fixed(options
|
|
55
|
+
layer: Layer.mergeAll(Layer.succeed(Probe.Probe, { ...fixed(options), observeIntersection: () => intersections.feed }), scrollLayer(scrollAtom)),
|
|
56
56
|
pushIntersection: (inView) => intersections.push(toIntersection(inView)),
|
|
57
57
|
pushScroll: (next) => AtomRegistry.AtomRegistry.use((registry) => Effect.sync(() => registry.set(scrollAtom, next))),
|
|
58
58
|
};
|
package/dist/probe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,oBAAoB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC,MAAM,WAAW,GAAiB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;AAC3G,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;AAC7C,mGAAmG;AACnG,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wardic/test",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.5",
|
|
4
4
|
"description": "Headless testing Layers for Wardic: a clock that replays the frames you give it, a renderer that records what it's asked to draw, and input you push, so animation code runs without a browser.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"animation",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"typecheck:tests": "../../node_modules/typescript-7/bin/tsc -p tsconfig.test.json"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@wardic/core": "1.0.0-rc.
|
|
51
|
+
"@wardic/core": "1.0.0-rc.5"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"effect": "^4.1.1"
|
package/src/index.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* under the test runner's fake timers, as https://wardic.dev/guides/testing shows.
|
|
9
9
|
*/
|
|
10
10
|
// The testing guide: #558.
|
|
11
|
-
export const VERSION = "1.0.0-rc.
|
|
11
|
+
export const VERSION = "1.0.0-rc.5"
|
|
12
12
|
|
|
13
13
|
export * as TestClock from "./clock.ts"
|
|
14
14
|
export * as TestRenderer from "./renderer.ts"
|
package/src/layer.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type * as Probe from "@wardic/core/Probe"
|
|
|
10
10
|
import * as ReducedMotion from "@wardic/core/ReducedMotion"
|
|
11
11
|
import * as RefreshFrameSource from "@wardic/core/RefreshFrameSource"
|
|
12
12
|
import type * as Renderer from "@wardic/core/Renderer"
|
|
13
|
+
import type * as ScrollSource from "@wardic/core/ScrollSource"
|
|
13
14
|
import { constUndefined, constVoid } from "effect/Function"
|
|
14
15
|
import * as Layer from "effect/Layer"
|
|
15
16
|
import { AtomRegistry } from "effect/reactivity"
|
|
@@ -27,8 +28,8 @@ const stillFrames: RefreshFrameSource.Shape = { requestFrame: constUndefined, ca
|
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* The full headless environment: deterministic Clock (driven by `frames`), a Refresh frame
|
|
30
|
-
* source that never calls back, recording Renderer, static Probe
|
|
31
|
-
* interpolator registry, a fresh AtomRegistry for reading Probe atoms
|
|
31
|
+
* source that never calls back, recording Renderer, static Probe and ScrollSource, silent
|
|
32
|
+
* InputSource, core's real interpolator registry, a fresh AtomRegistry for reading Probe atoms
|
|
32
33
|
* (`viewport`, `prefersReducedMotion`), and a fresh Drag activity, so one test's
|
|
33
34
|
* drag never blocks another's hover or press, and core's Frame loop over that
|
|
34
35
|
* Clock. Provide this in place of `DomLive` to test animation code without a
|
|
@@ -45,6 +46,7 @@ export const testLayer = (
|
|
|
45
46
|
| FrameLoop.FrameLoop
|
|
46
47
|
| Renderer.Renderer
|
|
47
48
|
| Probe.Probe
|
|
49
|
+
| ScrollSource.ScrollSource
|
|
48
50
|
| InputSource.InputSource
|
|
49
51
|
| InterpolatorRegistry.InterpolatorRegistry
|
|
50
52
|
| ReducedMotion.PositionalKeys
|
package/src/probe.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Probe from "@wardic/core/Probe"
|
|
2
|
+
import * as ScrollSource from "@wardic/core/ScrollSource"
|
|
2
3
|
import * as Arr from "effect/Array"
|
|
3
4
|
import * as Effect from "effect/Effect"
|
|
4
5
|
import * as Layer from "effect/Layer"
|
|
@@ -9,21 +10,22 @@ import * as Feeds from "./feeds.ts"
|
|
|
9
10
|
const ZERO_BOUNDS: Probe.Bounds = { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }
|
|
10
11
|
const VIEWPORT = { width: 1024, height: 768 }
|
|
11
12
|
/** A page that doesn't scroll: no range, and progress 1, as Motion reads a container with none. */
|
|
12
|
-
const STILL_SCROLL:
|
|
13
|
+
const STILL_SCROLL: ScrollSource.Scroll = { x: { current: 0, length: 0, progress: 1 }, y: { current: 0, length: 0, progress: 1 } }
|
|
13
14
|
|
|
14
15
|
/** A scripted in-view boolean as the Probe reports it, with no platform record. */
|
|
15
16
|
const toIntersection = (intersecting: boolean): Probe.Intersection => ({ intersecting })
|
|
16
17
|
|
|
17
18
|
/** Options for the static test Probe. */
|
|
18
|
-
// visible: #443 (`pageVisible` until #610). scroll: #234
|
|
19
|
+
// visible: #443 (`pageVisible` until #610). scroll: #234, a `ScrollSource` of its own since #518.
|
|
20
|
+
// intersection, an Input feed: #318.
|
|
19
21
|
export interface Options {
|
|
20
22
|
readonly bounds?: Probe.Bounds
|
|
21
23
|
readonly viewport?: { readonly width: number; readonly height: number }
|
|
22
24
|
readonly prefersReducedMotion?: boolean
|
|
23
25
|
/** Whether the Environment is shown: `true` when left out. */
|
|
24
26
|
readonly visible?: boolean
|
|
25
|
-
/** Every container's scroll, as `
|
|
26
|
-
readonly scroll?:
|
|
27
|
+
/** Every container's scroll, as the `ScrollSource` gives it: a page that doesn't scroll when left out. */
|
|
28
|
+
readonly scroll?: ScrollSource.Scroll
|
|
27
29
|
/**
|
|
28
30
|
* Script of intersection (in-view) booleans replayed by `observeIntersection`, an **Input feed**
|
|
29
31
|
* that ends after it. Mirrors the InputSource test harness: omitted (or empty) means it
|
|
@@ -35,29 +37,33 @@ export interface Options {
|
|
|
35
37
|
/**
|
|
36
38
|
* A static Probe: fixed bounds/viewport. `observeIntersection` replays the
|
|
37
39
|
* optional `intersection` script to each subscriber (empty by default, so it
|
|
38
|
-
* emits nothing); `observeResize` stays empty.
|
|
40
|
+
* emits nothing); `observeResize` stays empty. With it, a `ScrollSource`
|
|
41
|
+
* whose every container reads `scroll`, as the Probe's `scroll` did until #518.
|
|
39
42
|
*/
|
|
40
|
-
export const layer = (options: Options = {}): Layer.Layer<Probe.Probe> => {
|
|
43
|
+
export const layer = (options: Options = {}): Layer.Layer<Probe.Probe | ScrollSource.ScrollSource> => {
|
|
41
44
|
const { intersection = [], scroll = STILL_SCROLL } = options
|
|
42
|
-
return Layer.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
return Layer.mergeAll(
|
|
46
|
+
Layer.succeed(Probe.Probe, {
|
|
47
|
+
...fixed(options),
|
|
48
|
+
observeIntersection: () => Feeds.script(Arr.map(intersection, toIntersection)),
|
|
49
|
+
}),
|
|
50
|
+
scrollLayer(Atom.make(scroll)),
|
|
51
|
+
)
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
* and one scroll Atom for every container, target and offset (#234).
|
|
51
|
-
*/
|
|
52
|
-
const fixed = ({ bounds = ZERO_BOUNDS, viewport = VIEWPORT, prefersReducedMotion = false, visible = true }: Options, scroll: Atom.Atom<Probe.Scroll>) => ({
|
|
54
|
+
/** Both Probes' fixed part: the bounds, the viewport, the preference and the page's visibility, each defaulted, and no resizes. */
|
|
55
|
+
const fixed = ({ bounds = ZERO_BOUNDS, viewport = VIEWPORT, prefersReducedMotion = false, visible = true }: Options) => ({
|
|
53
56
|
measure: () => Effect.sync(() => bounds),
|
|
54
57
|
viewport: Atom.make(viewport),
|
|
55
58
|
prefersReducedMotion: Atom.make(prefersReducedMotion),
|
|
56
59
|
visible: Atom.make(visible),
|
|
57
|
-
scroll: () => Effect.succeed(scroll),
|
|
58
60
|
observeResize: () => Stream.empty,
|
|
59
61
|
})
|
|
60
62
|
|
|
63
|
+
/** One scroll Atom for every container, target and offset (#234). */
|
|
64
|
+
const scrollLayer = (scroll: Atom.Atom<ScrollSource.Scroll>): Layer.Layer<ScrollSource.ScrollSource> =>
|
|
65
|
+
Layer.succeed(ScrollSource.ScrollSource, { scroll: () => Effect.succeed(scroll) })
|
|
66
|
+
|
|
61
67
|
/**
|
|
62
68
|
* A push-based Probe for tests that need to interleave intersection
|
|
63
69
|
* (in-view/out-of-view) transitions with other effects on their own schedule —
|
|
@@ -71,17 +77,17 @@ const fixed = ({ bounds = ZERO_BOUNDS, viewport = VIEWPORT, prefersReducedMotion
|
|
|
71
77
|
*/
|
|
72
78
|
// The hub: #318. No yield: ADR-0032. Scroll: #234.
|
|
73
79
|
export const pushable = (options: Options = {}): Effect.Effect<{
|
|
74
|
-
readonly layer: Layer.Layer<Probe.Probe>
|
|
80
|
+
readonly layer: Layer.Layer<Probe.Probe | ScrollSource.ScrollSource>
|
|
75
81
|
readonly pushIntersection: (inView: boolean) => Effect.Effect<void>
|
|
76
|
-
readonly pushScroll: (scroll:
|
|
82
|
+
readonly pushScroll: (scroll: ScrollSource.Scroll) => Effect.Effect<void, never, AtomRegistry.AtomRegistry>
|
|
77
83
|
}> =>
|
|
78
84
|
Effect.sync(() => {
|
|
79
85
|
const intersections = Feeds.hub<Probe.Intersection>()
|
|
80
86
|
const { scroll = STILL_SCROLL } = options
|
|
81
87
|
const scrollAtom = Atom.make(scroll)
|
|
82
88
|
return {
|
|
83
|
-
layer: Layer.succeed(Probe.Probe, { ...fixed(options
|
|
89
|
+
layer: Layer.mergeAll(Layer.succeed(Probe.Probe, { ...fixed(options), observeIntersection: () => intersections.feed }), scrollLayer(scrollAtom)),
|
|
84
90
|
pushIntersection: (inView: boolean) => intersections.push(toIntersection(inView)),
|
|
85
|
-
pushScroll: (next:
|
|
91
|
+
pushScroll: (next: ScrollSource.Scroll) => AtomRegistry.AtomRegistry.use((registry) => Effect.sync(() => registry.set(scrollAtom, next))),
|
|
86
92
|
}
|
|
87
93
|
})
|