@flighthq/render 0.3.1-next.509.c235802 → 0.3.1-next.616.aa7ae7f
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/explainScene2DCoverage.d.ts +2 -2
- package/dist/explainScene2DCoverage.d.ts.map +1 -1
- package/dist/explainScene2DCoverage.js +47 -9
- package/dist/explainScene2DCoverage.js.map +1 -1
- package/dist/renderRegistryGuards.js +4 -2
- package/dist/renderRegistryGuards.js.map +1 -1
- package/package.json +11 -11
- package/src/explainScene2DCoverage.test.ts +64 -13
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RenderState, Scene2DKindUsage, SceneCoverageEntry } from '@flighthq/types/contract';
|
|
2
|
-
export declare function explainScene2DCoverage(out: SceneCoverageEntry[], state: RenderState, usage: Readonly<Scene2DKindUsage
|
|
1
|
+
import type { RenderState, Scene2DKindUsage, SceneCoverageCatalog, SceneCoverageEntry } from '@flighthq/types/contract';
|
|
2
|
+
export declare function explainScene2DCoverage(out: SceneCoverageEntry[], state: RenderState, usage: Readonly<Scene2DKindUsage>, catalog: SceneCoverageCatalog): void;
|
|
3
3
|
export declare function hasScene2DCoverage(state: RenderState, usage: Readonly<Scene2DKindUsage>): boolean;
|
|
4
4
|
//# sourceMappingURL=explainScene2DCoverage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explainScene2DCoverage.d.ts","sourceRoot":"","sources":["../src/explainScene2DCoverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"explainScene2DCoverage.d.ts","sourceRoot":"","sources":["../src/explainScene2DCoverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAiBlC,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,kBAAkB,EAAE,EACzB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACjC,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CAGN;AAID,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAEjG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RenderRegistry, SceneCoverage } from '@flighthq/types/contract';
|
|
1
|
+
import { RenderRegistry, RequirementFacet, SceneCoverage } from '@flighthq/types/contract';
|
|
2
2
|
import { getRenderStateRuntime } from './renderState';
|
|
3
3
|
// Clears `out`, then reports every requirement in `usage` that any 2D backend answers the same way,
|
|
4
4
|
// with how well this state is wired for it — satisfied entries included, so one call is a manifest.
|
|
@@ -10,18 +10,20 @@ import { getRenderStateRuntime } from './renderState';
|
|
|
10
10
|
//
|
|
11
11
|
// Unlike the 3D seam, node kinds ARE a requirement here: the 2D pipeline resolves every node through
|
|
12
12
|
// `registerRenderer(state, kind, renderer)`, where the 3D pipeline collects meshes structurally.
|
|
13
|
-
|
|
13
|
+
// `catalog` is the caller's complete backend inventory; an unserved requirement uses its first ordered
|
|
14
|
+
// registration as the primary remedy, while a satisfied requirement needs no catalog lookup.
|
|
15
|
+
export function explainScene2DCoverage(out, state, usage, catalog) {
|
|
14
16
|
out.length = 0;
|
|
15
|
-
collectScene2DCoverageGaps(out, state, usage, false);
|
|
17
|
+
collectScene2DCoverageGaps(out, state, usage, false, catalog);
|
|
16
18
|
}
|
|
17
19
|
// Whether this state can serve every node kind and shape command `usage` names. Stops at the first
|
|
18
20
|
// shortfall and never allocates. Use the explain form to find out WHICH requirement and how badly.
|
|
19
21
|
export function hasScene2DCoverage(state, usage) {
|
|
20
|
-
return !collectScene2DCoverageGaps(null, state, usage, true);
|
|
22
|
+
return !collectScene2DCoverageGaps(null, state, usage, true, null);
|
|
21
23
|
}
|
|
22
24
|
// The single implementation both tiers read, so the boolean can never disagree with the explanation.
|
|
23
25
|
// `found` counts only real shortfalls, so appending satisfied entries to `out` never flips the predicate.
|
|
24
|
-
function collectScene2DCoverageGaps(out, state, usage, stopAtFirst) {
|
|
26
|
+
function collectScene2DCoverageGaps(out, state, usage, stopAtFirst, catalog) {
|
|
25
27
|
let found = false;
|
|
26
28
|
const runtime = getRenderStateRuntime(state);
|
|
27
29
|
// A node kind with no renderer produces no render proxy, so the node and its whole subtree are
|
|
@@ -29,13 +31,18 @@ function collectScene2DCoverageGaps(out, state, usage, stopAtFirst) {
|
|
|
29
31
|
for (let i = 0; i < usage.nodeKinds.length; i++) {
|
|
30
32
|
const kind = usage.nodeKinds[i];
|
|
31
33
|
if (runtime.rendererMap.has(kind)) {
|
|
32
|
-
out?.push({
|
|
34
|
+
out?.push({
|
|
35
|
+
coverage: SceneCoverage.Satisfied,
|
|
36
|
+
facet: RequirementFacet.SceneNodeKind,
|
|
37
|
+
kind,
|
|
38
|
+
registry: RenderRegistry.NodeRenderer,
|
|
39
|
+
});
|
|
33
40
|
continue;
|
|
34
41
|
}
|
|
35
42
|
found = true;
|
|
36
43
|
if (stopAtFirst)
|
|
37
44
|
return true;
|
|
38
|
-
out?.push(
|
|
45
|
+
out?.push(createShortfallEntry(catalog, false, RequirementFacet.SceneNodeKind, kind, RenderRegistry.NodeRenderer));
|
|
39
46
|
}
|
|
40
47
|
// Only meaningful for a state that rasterizes shapes. A GL or WebGPU state drawing every shape
|
|
41
48
|
// through the mesh path never replays a command, so these entries are reported and simply not acted
|
|
@@ -44,14 +51,45 @@ function collectScene2DCoverageGaps(out, state, usage, stopAtFirst) {
|
|
|
44
51
|
for (let i = 0; i < usage.shapeCommandKeys.length; i++) {
|
|
45
52
|
const kind = usage.shapeCommandKeys[i];
|
|
46
53
|
if (commands?.has(kind) === true) {
|
|
47
|
-
out?.push({
|
|
54
|
+
out?.push({
|
|
55
|
+
coverage: SceneCoverage.Satisfied,
|
|
56
|
+
facet: RequirementFacet.SceneShapeCommand,
|
|
57
|
+
kind,
|
|
58
|
+
registry: RenderRegistry.ShapeCommandHandler,
|
|
59
|
+
});
|
|
48
60
|
continue;
|
|
49
61
|
}
|
|
50
62
|
found = true;
|
|
51
63
|
if (stopAtFirst)
|
|
52
64
|
return true;
|
|
53
|
-
out?.push(
|
|
65
|
+
out?.push(createShortfallEntry(catalog, false, RequirementFacet.SceneShapeCommand, kind, RenderRegistry.ShapeCommandHandler));
|
|
54
66
|
}
|
|
55
67
|
return found;
|
|
56
68
|
}
|
|
69
|
+
function createShortfallEntry(catalog, fallback, facet, kind, registry) {
|
|
70
|
+
const registration = findCatalogRegistration(catalog, kind, registry);
|
|
71
|
+
const base = { facet, kind, registry };
|
|
72
|
+
if (registration === null) {
|
|
73
|
+
return {
|
|
74
|
+
...base,
|
|
75
|
+
coverage: fallback ? SceneCoverage.FallbackUnavailable : SceneCoverage.Unavailable,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
...base,
|
|
80
|
+
coverage: fallback ? SceneCoverage.FallbackRemediable : SceneCoverage.Unregistered,
|
|
81
|
+
module: registration.module,
|
|
82
|
+
registrar: registration.registrar,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Package-private and row-agnostic: generated, probed, and fixture catalogs all feed the same seam.
|
|
86
|
+
function findCatalogRegistration(catalog, kind, registry) {
|
|
87
|
+
if (catalog === null)
|
|
88
|
+
return null;
|
|
89
|
+
for (const entry of catalog) {
|
|
90
|
+
if (entry.kind === kind && entry.registry === registry)
|
|
91
|
+
return entry.registrations[0] ?? null;
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
57
95
|
//# sourceMappingURL=explainScene2DCoverage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explainScene2DCoverage.js","sourceRoot":"","sources":["../src/explainScene2DCoverage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"explainScene2DCoverage.js","sourceRoot":"","sources":["../src/explainScene2DCoverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,9 +32,11 @@ function getRenderRegistryMissMessage(state, registry) {
|
|
|
32
32
|
return 'computeRenderEffectPadding: effect kind has no registered padding resolver — call registerRenderEffectPaddingResolver(state, kind, resolver)';
|
|
33
33
|
// Reported by the resource layer, not the frame path: a material kind with no lister has its
|
|
34
34
|
// texture slots invisible to anything that walks materials. Discovery no longer depends on this
|
|
35
|
-
// (it reads the resource back-edge)
|
|
35
|
+
// (it reads the resource back-edge). On an all-unlisted mesh, reveal-on-resolve leaves the starting
|
|
36
|
+
// alpha unchanged. On a mixed mesh, it can reveal after the listed textures settle while an unlisted
|
|
37
|
+
// texture is still pending.
|
|
36
38
|
case RenderRegistry.MaterialTextureLister:
|
|
37
|
-
return
|
|
39
|
+
return "a material kind in this scene has no registered texture lister, so an all-unlisted mesh gets no fade, while a mixed mesh can reveal before that material's textures settle and show a later texture pop-in — call registerScene3DMaterialTextures(registry, kind, lister), or the named door for that family";
|
|
38
40
|
// Reported only by the GPU backends, where an unresolved material means the node does not draw at
|
|
39
41
|
// all. The Canvas renderer treats a missing material renderer as "draw normally", so the same
|
|
40
42
|
// absence there is the ordinary case rather than a defect.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderRegistryGuards.js","sourceRoot":"","sources":["../src/renderRegistryGuards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE,MAAM,UAAU,8BAA8B,CAAC,KAAkB;IAC/D,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAAkB;IAC3D,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,OAAO,GAAG,EAAE,YAAY,CAAC;IAC/B,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9B,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5B,aAAa,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE;QAClF,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAkB;IAC5D,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7C,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5E,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB;KAC7D,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAkB,EAAE,QAAwB;IAChF,QAAQ,QAAQ,EAAE,CAAC;QACjB,6FAA6F;QAC7F,kCAAkC;QAClC,KAAK,cAAc,CAAC,gBAAgB;YAClC,OAAO,mKAAmK,CAAC;QAC7K,KAAK,cAAc,CAAC,qBAAqB;YACvC,OAAO,8IAA8I,CAAC;QACxJ,6FAA6F;QAC7F,gGAAgG;QAChG
|
|
1
|
+
{"version":3,"file":"renderRegistryGuards.js","sourceRoot":"","sources":["../src/renderRegistryGuards.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/render",
|
|
3
|
-
"version": "0.3.1-next.
|
|
3
|
+
"version": "0.3.1-next.616.aa7ae7f",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/adjustments": "0.3.1-next.
|
|
42
|
-
"@flighthq/color": "0.3.1-next.
|
|
43
|
-
"@flighthq/entity": "0.3.1-next.
|
|
44
|
-
"@flighthq/geometry": "0.3.1-next.
|
|
45
|
-
"@flighthq/log": "0.3.1-next.
|
|
46
|
-
"@flighthq/materials": "0.3.1-next.
|
|
47
|
-
"@flighthq/mesh": "0.3.1-next.
|
|
48
|
-
"@flighthq/node": "0.3.1-next.
|
|
49
|
-
"@flighthq/signals": "0.3.1-next.
|
|
50
|
-
"@flighthq/types": "0.3.1-next.
|
|
41
|
+
"@flighthq/adjustments": "0.3.1-next.616.aa7ae7f",
|
|
42
|
+
"@flighthq/color": "0.3.1-next.616.aa7ae7f",
|
|
43
|
+
"@flighthq/entity": "0.3.1-next.616.aa7ae7f",
|
|
44
|
+
"@flighthq/geometry": "0.3.1-next.616.aa7ae7f",
|
|
45
|
+
"@flighthq/log": "0.3.1-next.616.aa7ae7f",
|
|
46
|
+
"@flighthq/materials": "0.3.1-next.616.aa7ae7f",
|
|
47
|
+
"@flighthq/mesh": "0.3.1-next.616.aa7ae7f",
|
|
48
|
+
"@flighthq/node": "0.3.1-next.616.aa7ae7f",
|
|
49
|
+
"@flighthq/signals": "0.3.1-next.616.aa7ae7f",
|
|
50
|
+
"@flighthq/types": "0.3.1-next.616.aa7ae7f"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@flighthq/camera": "*",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Renderer, Scene2DKindUsage, SceneCoverageEntry } from '@flighthq/types/contract';
|
|
2
|
-
import { RenderRegistry, SceneCoverage } from '@flighthq/types/contract';
|
|
1
|
+
import type { Renderer, Scene2DKindUsage, SceneCoverageCatalog, SceneCoverageEntry } from '@flighthq/types/contract';
|
|
2
|
+
import { RenderRegistry, RequirementFacet, SceneCoverage } from '@flighthq/types/contract';
|
|
3
3
|
import { describe, expect, it } from 'vitest';
|
|
4
4
|
|
|
5
5
|
import { explainScene2DCoverage, hasScene2DCoverage } from './explainScene2DCoverage';
|
|
@@ -8,14 +8,38 @@ import { createRenderState } from './renderState';
|
|
|
8
8
|
import { getRenderStateRuntime } from './renderState';
|
|
9
9
|
|
|
10
10
|
const renderer: Renderer = { createData: () => null, submit: () => {} } as unknown as Renderer;
|
|
11
|
+
const coverageCatalog: SceneCoverageCatalog = [
|
|
12
|
+
{
|
|
13
|
+
kind: 'Shape',
|
|
14
|
+
registrations: [
|
|
15
|
+
{ module: '@flighthq/scene2d', registrar: 'registerShapeRenderer' },
|
|
16
|
+
{ module: '@flighthq/scene2d-canvas', registrar: 'registerCanvasShapeCommands' },
|
|
17
|
+
],
|
|
18
|
+
registry: RenderRegistry.NodeRenderer,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
kind: 'Sprite',
|
|
22
|
+
registrations: [{ module: '@flighthq/scene2d', registrar: 'registerSpriteRenderer' }],
|
|
23
|
+
registry: RenderRegistry.NodeRenderer,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
kind: 'beginFill',
|
|
27
|
+
registrations: [{ module: '@flighthq/scene2d-canvas', registrar: 'registerCanvasShapeCommands' }],
|
|
28
|
+
registry: RenderRegistry.ShapeCommandHandler,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
11
31
|
|
|
12
32
|
function usage(overrides: Partial<Scene2DKindUsage> = {}): Scene2DKindUsage {
|
|
13
33
|
return { blendModes: [], materialKinds: [], nodeKinds: [], shapeCommandKeys: [], ...overrides };
|
|
14
34
|
}
|
|
15
35
|
|
|
16
|
-
function entries(
|
|
36
|
+
function entries(
|
|
37
|
+
state: ReturnType<typeof createRenderState>,
|
|
38
|
+
u: Scene2DKindUsage,
|
|
39
|
+
catalog: SceneCoverageCatalog = coverageCatalog,
|
|
40
|
+
): SceneCoverageEntry[] {
|
|
17
41
|
const out: SceneCoverageEntry[] = [];
|
|
18
|
-
explainScene2DCoverage(out, state, u);
|
|
42
|
+
explainScene2DCoverage(out, state, u, catalog);
|
|
19
43
|
return out;
|
|
20
44
|
}
|
|
21
45
|
|
|
@@ -27,9 +51,27 @@ function wireShapeCommand(state: ReturnType<typeof createRenderState>, key: stri
|
|
|
27
51
|
}
|
|
28
52
|
|
|
29
53
|
describe('explainScene2DCoverage', () => {
|
|
30
|
-
it('reports an unregistered node kind
|
|
54
|
+
it('reports an unregistered node kind with the primary catalog remedy', () => {
|
|
31
55
|
expect(entries(createRenderState(), usage({ nodeKinds: ['Shape'] }))).toEqual([
|
|
32
|
-
{
|
|
56
|
+
{
|
|
57
|
+
coverage: SceneCoverage.Unregistered,
|
|
58
|
+
facet: RequirementFacet.SceneNodeKind,
|
|
59
|
+
kind: 'Shape',
|
|
60
|
+
module: '@flighthq/scene2d',
|
|
61
|
+
registrar: 'registerShapeRenderer',
|
|
62
|
+
registry: RenderRegistry.NodeRenderer,
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('reports an uncatalogued node kind as Unavailable, with no remedy fields', () => {
|
|
68
|
+
expect(entries(createRenderState(), usage({ nodeKinds: ['Shape'] }), [])).toEqual([
|
|
69
|
+
{
|
|
70
|
+
coverage: SceneCoverage.Unavailable,
|
|
71
|
+
facet: RequirementFacet.SceneNodeKind,
|
|
72
|
+
kind: 'Shape',
|
|
73
|
+
registry: RenderRegistry.NodeRenderer,
|
|
74
|
+
},
|
|
33
75
|
]);
|
|
34
76
|
});
|
|
35
77
|
|
|
@@ -37,14 +79,22 @@ describe('explainScene2DCoverage', () => {
|
|
|
37
79
|
const state = createRenderState();
|
|
38
80
|
registerRenderer(state, 'Shape', renderer);
|
|
39
81
|
expect(entries(state, usage({ nodeKinds: ['Shape'] }))).toEqual([
|
|
40
|
-
{
|
|
82
|
+
{
|
|
83
|
+
coverage: SceneCoverage.Satisfied,
|
|
84
|
+
facet: RequirementFacet.SceneNodeKind,
|
|
85
|
+
kind: 'Shape',
|
|
86
|
+
registry: RenderRegistry.NodeRenderer,
|
|
87
|
+
},
|
|
41
88
|
]);
|
|
42
89
|
});
|
|
43
90
|
|
|
44
91
|
it('reports an unhandled shape command key against the state that would replay it', () => {
|
|
45
92
|
expect(entries(createRenderState(), usage({ shapeCommandKeys: ['beginFill'] }))).toContainEqual({
|
|
46
|
-
coverage: SceneCoverage.
|
|
93
|
+
coverage: SceneCoverage.Unregistered,
|
|
94
|
+
facet: RequirementFacet.SceneShapeCommand,
|
|
47
95
|
kind: 'beginFill',
|
|
96
|
+
module: '@flighthq/scene2d-canvas',
|
|
97
|
+
registrar: 'registerCanvasShapeCommands',
|
|
48
98
|
registry: RenderRegistry.ShapeCommandHandler,
|
|
49
99
|
});
|
|
50
100
|
});
|
|
@@ -54,6 +104,7 @@ describe('explainScene2DCoverage', () => {
|
|
|
54
104
|
wireShapeCommand(state, 'beginFill');
|
|
55
105
|
expect(entries(state, usage({ shapeCommandKeys: ['beginFill'] }))).toContainEqual({
|
|
56
106
|
coverage: SceneCoverage.Satisfied,
|
|
107
|
+
facet: RequirementFacet.SceneShapeCommand,
|
|
57
108
|
kind: 'beginFill',
|
|
58
109
|
registry: RenderRegistry.ShapeCommandHandler,
|
|
59
110
|
});
|
|
@@ -64,7 +115,7 @@ describe('explainScene2DCoverage', () => {
|
|
|
64
115
|
registerRenderer(state, 'Shape', renderer);
|
|
65
116
|
const found = entries(state, usage({ nodeKinds: ['Shape', 'Sprite'], shapeCommandKeys: ['beginFill'] }));
|
|
66
117
|
expect(found).toHaveLength(3);
|
|
67
|
-
expect(found.filter((e) => e.coverage
|
|
118
|
+
expect(found.filter((e) => e.coverage !== SceneCoverage.Satisfied).map((e) => e.kind)).toEqual([
|
|
68
119
|
'Sprite',
|
|
69
120
|
'beginFill',
|
|
70
121
|
]);
|
|
@@ -74,9 +125,9 @@ describe('explainScene2DCoverage', () => {
|
|
|
74
125
|
const state = createRenderState();
|
|
75
126
|
const u = usage({ nodeKinds: ['Shape'] });
|
|
76
127
|
const out: SceneCoverageEntry[] = [];
|
|
77
|
-
explainScene2DCoverage(out, state, u);
|
|
128
|
+
explainScene2DCoverage(out, state, u, coverageCatalog);
|
|
78
129
|
const first = out.length;
|
|
79
|
-
explainScene2DCoverage(out, state, u);
|
|
130
|
+
explainScene2DCoverage(out, state, u, coverageCatalog);
|
|
80
131
|
expect(out).toHaveLength(first);
|
|
81
132
|
});
|
|
82
133
|
});
|
|
@@ -92,7 +143,7 @@ describe('hasScene2DCoverage', () => {
|
|
|
92
143
|
wireShapeCommand(state, 'beginFill');
|
|
93
144
|
const u = usage({ nodeKinds: ['Shape'], shapeCommandKeys: ['beginFill'] });
|
|
94
145
|
const out: SceneCoverageEntry[] = [];
|
|
95
|
-
explainScene2DCoverage(out, state, u);
|
|
146
|
+
explainScene2DCoverage(out, state, u, coverageCatalog);
|
|
96
147
|
expect(out.every((e) => e.coverage === SceneCoverage.Satisfied)).toBe(true);
|
|
97
148
|
expect(hasScene2DCoverage(state, u)).toBe(true);
|
|
98
149
|
});
|
|
@@ -102,7 +153,7 @@ describe('hasScene2DCoverage', () => {
|
|
|
102
153
|
registerRenderer(state, 'Shape', renderer);
|
|
103
154
|
const u = usage({ nodeKinds: ['Shape', 'Sprite'] });
|
|
104
155
|
const out: SceneCoverageEntry[] = [];
|
|
105
|
-
explainScene2DCoverage(out, state, u);
|
|
156
|
+
explainScene2DCoverage(out, state, u, coverageCatalog);
|
|
106
157
|
const gaps = out.filter((e) => e.coverage !== SceneCoverage.Satisfied);
|
|
107
158
|
expect(hasScene2DCoverage(state, u)).toBe(gaps.length === 0);
|
|
108
159
|
});
|