@deck.gl/test-utils 9.3.0-alpha.3 → 9.3.0-alpha.6
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.cjs +64 -24
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lifecycle-test.d.ts +31 -27
- package/dist/lifecycle-test.d.ts.map +1 -1
- package/dist/lifecycle-test.js +40 -21
- package/dist/lifecycle-test.js.map +1 -1
- package/dist/tape.d.ts +22 -0
- package/dist/tape.d.ts.map +1 -0
- package/dist/tape.js +50 -0
- package/dist/tape.js.map +1 -0
- package/dist/test-runner.js +3 -3
- package/dist/test-runner.js.map +1 -1
- package/dist/utils/setup-gl.d.ts +1 -2
- package/dist/utils/setup-gl.d.ts.map +1 -1
- package/dist/utils/setup-gl.js +1 -0
- package/dist/utils/setup-gl.js.map +1 -1
- package/dist/vitest.cjs +465 -0
- package/dist/vitest.cjs.map +7 -0
- package/dist/vitest.d.ts +17 -0
- package/dist/vitest.d.ts.map +1 -0
- package/dist/vitest.js +28 -0
- package/dist/vitest.js.map +1 -0
- package/package.json +19 -8
- package/src/globals.d.ts +42 -0
- package/src/index.ts +3 -7
- package/src/lifecycle-test.ts +98 -50
- package/src/tape.ts +85 -0
- package/src/test-runner.ts +3 -3
- package/src/utils/setup-gl.ts +1 -2
- package/src/vitest.ts +49 -0
package/dist/index.cjs
CHANGED
|
@@ -29,8 +29,8 @@ __export(dist_exports, {
|
|
|
29
29
|
gl: () => gl,
|
|
30
30
|
testInitializeLayer: () => testInitializeLayer,
|
|
31
31
|
testInitializeLayerAsync: () => testInitializeLayerAsync,
|
|
32
|
-
testLayer: () =>
|
|
33
|
-
testLayerAsync: () =>
|
|
32
|
+
testLayer: () => testLayer2,
|
|
33
|
+
testLayerAsync: () => testLayerAsync2,
|
|
34
34
|
toLowPrecision: () => toLowPrecision
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(dist_exports);
|
|
@@ -69,9 +69,11 @@ var _a;
|
|
|
69
69
|
var gl = ((_a = import_test_utils.webglDevice) == null ? void 0 : _a.gl) || 1;
|
|
70
70
|
globalThis.glContext = globalThis.glContext || gl;
|
|
71
71
|
|
|
72
|
+
// dist/tape.js
|
|
73
|
+
var import_test_utils2 = require("@probe.gl/test-utils");
|
|
74
|
+
|
|
72
75
|
// dist/lifecycle-test.js
|
|
73
76
|
var import_core = require("@deck.gl/core");
|
|
74
|
-
var import_test_utils2 = require("@probe.gl/test-utils");
|
|
75
77
|
var testViewport = new import_core.MapView({}).makeViewport({
|
|
76
78
|
width: 100,
|
|
77
79
|
height: 100,
|
|
@@ -115,14 +117,14 @@ async function testInitializeLayerAsync(opts) {
|
|
|
115
117
|
return null;
|
|
116
118
|
}
|
|
117
119
|
function testLayer(opts) {
|
|
118
|
-
const { Layer, testCases = [], spies = [], onError = defaultOnError } = opts;
|
|
120
|
+
const { Layer, testCases = [], spies = [], onError = defaultOnError, createSpy, resetSpy } = opts;
|
|
119
121
|
const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);
|
|
120
122
|
let layer = new Layer();
|
|
121
123
|
for (const testCase of testCases) {
|
|
122
124
|
const oldState = { ...layer.state };
|
|
123
|
-
const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies);
|
|
125
|
+
const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies, createSpy);
|
|
124
126
|
runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
|
|
125
|
-
Object.keys(spyMap).forEach((k) => spyMap[k]
|
|
127
|
+
Object.keys(spyMap).forEach((k) => resetSpy(spyMap[k]));
|
|
126
128
|
layer = newLayer;
|
|
127
129
|
}
|
|
128
130
|
const error = cleanupAfterLayerTests(resources);
|
|
@@ -131,21 +133,21 @@ function testLayer(opts) {
|
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
async function testLayerAsync(opts) {
|
|
134
|
-
const { Layer, testCases = [], spies = [], onError = defaultOnError } = opts;
|
|
136
|
+
const { Layer, testCases = [], spies = [], onError = defaultOnError, createSpy, resetSpy } = opts;
|
|
135
137
|
const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);
|
|
136
138
|
let layer = new Layer();
|
|
137
139
|
for (const testCase of testCases) {
|
|
138
140
|
const oldState = { ...layer.state };
|
|
139
|
-
const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies);
|
|
141
|
+
const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies, createSpy);
|
|
140
142
|
runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
|
|
141
143
|
while (!newLayer.isLoaded) {
|
|
142
144
|
await update(resources);
|
|
143
145
|
runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
|
|
144
146
|
}
|
|
145
|
-
Object.keys(spyMap).forEach((k) => spyMap[k]
|
|
147
|
+
Object.keys(spyMap).forEach((k) => resetSpy(spyMap[k]));
|
|
146
148
|
layer = newLayer;
|
|
147
149
|
}
|
|
148
|
-
const error =
|
|
150
|
+
const error = await cleanupAfterLayerTestsAsync(resources);
|
|
149
151
|
if (error) {
|
|
150
152
|
onError(error, `${Layer.layerName} should delete all resources`);
|
|
151
153
|
}
|
|
@@ -167,13 +169,14 @@ function cleanupAfterLayerTests({ layerManager, deckRenderer, oldResourceCounts
|
|
|
167
169
|
layerManager.setLayers([]);
|
|
168
170
|
layerManager.finalize();
|
|
169
171
|
deckRenderer.finalize();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
return getResourceCountDelta(oldResourceCounts);
|
|
173
|
+
}
|
|
174
|
+
async function cleanupAfterLayerTestsAsync({ layerManager, deckRenderer, oldResourceCounts }) {
|
|
175
|
+
layerManager.setLayers([]);
|
|
176
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
177
|
+
layerManager.finalize();
|
|
178
|
+
deckRenderer.finalize();
|
|
179
|
+
return getResourceCountDelta(oldResourceCounts);
|
|
177
180
|
}
|
|
178
181
|
function getResourceCounts() {
|
|
179
182
|
const resourceStats = luma.stats.get("Resource Counts");
|
|
@@ -182,11 +185,20 @@ function getResourceCounts() {
|
|
|
182
185
|
Buffer: resourceStats.get("Buffers Active").count
|
|
183
186
|
};
|
|
184
187
|
}
|
|
185
|
-
function
|
|
188
|
+
function getResourceCountDelta(oldResourceCounts) {
|
|
189
|
+
const resourceCounts = getResourceCounts();
|
|
190
|
+
for (const resourceName in resourceCounts) {
|
|
191
|
+
if (resourceCounts[resourceName] !== oldResourceCounts[resourceName]) {
|
|
192
|
+
return new Error(`${resourceCounts[resourceName] - oldResourceCounts[resourceName]} ${resourceName}s`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
function injectSpies(layer, spies, spyFactory) {
|
|
186
198
|
const spyMap = {};
|
|
187
199
|
if (spies) {
|
|
188
200
|
for (const functionName of spies) {
|
|
189
|
-
spyMap[functionName] = (
|
|
201
|
+
spyMap[functionName] = spyFactory(Object.getPrototypeOf(layer), functionName);
|
|
190
202
|
}
|
|
191
203
|
}
|
|
192
204
|
return spyMap;
|
|
@@ -205,7 +217,7 @@ function runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap) {
|
|
|
205
217
|
});
|
|
206
218
|
}
|
|
207
219
|
}
|
|
208
|
-
function runLayerTestUpdate(testCase, { layerManager, deckRenderer }, layer, spies) {
|
|
220
|
+
function runLayerTestUpdate(testCase, { layerManager, deckRenderer }, layer, spies, spyFactory) {
|
|
209
221
|
const { props, updateProps, onBeforeUpdate, viewport = layerManager.context.viewport } = testCase;
|
|
210
222
|
if (onBeforeUpdate) {
|
|
211
223
|
onBeforeUpdate({ layer, testCase });
|
|
@@ -216,7 +228,7 @@ function runLayerTestUpdate(testCase, { layerManager, deckRenderer }, layer, spi
|
|
|
216
228
|
layer = layer.clone(updateProps);
|
|
217
229
|
}
|
|
218
230
|
spies = testCase.spies || spies;
|
|
219
|
-
const spyMap = injectSpies(layer, spies);
|
|
231
|
+
const spyMap = injectSpies(layer, spies, spyFactory);
|
|
220
232
|
const drawLayers = () => {
|
|
221
233
|
deckRenderer.renderLayers({
|
|
222
234
|
pass: "test",
|
|
@@ -257,6 +269,34 @@ function update({ layerManager, deckRenderer }) {
|
|
|
257
269
|
});
|
|
258
270
|
}
|
|
259
271
|
|
|
272
|
+
// dist/tape.js
|
|
273
|
+
var _hasWarnedCreateSpy = false;
|
|
274
|
+
var _hasWarnedResetSpy = false;
|
|
275
|
+
function getDefaultSpyFactory() {
|
|
276
|
+
if (!_hasWarnedCreateSpy) {
|
|
277
|
+
_hasWarnedCreateSpy = true;
|
|
278
|
+
console.warn("[@deck.gl/test-utils] Implicit @probe.gl/test-utils usage is deprecated. Pass createSpy option: createSpy: (obj, method) => vi.spyOn(obj, method) for vitest, or createSpy: makeSpy for probe.gl.");
|
|
279
|
+
}
|
|
280
|
+
return import_test_utils2.makeSpy;
|
|
281
|
+
}
|
|
282
|
+
function getDefaultResetSpy() {
|
|
283
|
+
if (!_hasWarnedResetSpy) {
|
|
284
|
+
_hasWarnedResetSpy = true;
|
|
285
|
+
console.warn("[@deck.gl/test-utils] Implicit spy reset is deprecated. Pass resetSpy option: resetSpy: (spy) => spy.mockRestore() for vitest, or resetSpy: (spy) => spy.reset() for probe.gl.");
|
|
286
|
+
}
|
|
287
|
+
return (spy) => spy.reset();
|
|
288
|
+
}
|
|
289
|
+
function testLayer2(opts) {
|
|
290
|
+
const createSpy = opts.createSpy || getDefaultSpyFactory();
|
|
291
|
+
const resetSpy = opts.resetSpy || getDefaultResetSpy();
|
|
292
|
+
testLayer({ ...opts, createSpy, resetSpy });
|
|
293
|
+
}
|
|
294
|
+
async function testLayerAsync2(opts) {
|
|
295
|
+
const createSpy = opts.createSpy || getDefaultSpyFactory();
|
|
296
|
+
const resetSpy = opts.resetSpy || getDefaultResetSpy();
|
|
297
|
+
await testLayerAsync({ ...opts, createSpy, resetSpy });
|
|
298
|
+
}
|
|
299
|
+
|
|
260
300
|
// dist/generate-layer-tests.js
|
|
261
301
|
var import_core2 = require("@deck.gl/core");
|
|
262
302
|
function noop() {
|
|
@@ -540,15 +580,15 @@ var TestRunner = class {
|
|
|
540
580
|
const task = this.runTestCase(testCase);
|
|
541
581
|
const timeoutTask = new Promise((_, reject) => {
|
|
542
582
|
setTimeout(() => {
|
|
543
|
-
reject(
|
|
583
|
+
reject(`Timeout after ${timeout}ms`);
|
|
544
584
|
}, timeout);
|
|
545
585
|
});
|
|
546
586
|
try {
|
|
547
587
|
await Promise.race([task, timeoutTask]);
|
|
548
588
|
await this.assert(testCase);
|
|
549
589
|
} catch (err) {
|
|
550
|
-
if (err === "Timeout") {
|
|
551
|
-
this.fail({ error:
|
|
590
|
+
if (typeof err === "string" && err.startsWith("Timeout")) {
|
|
591
|
+
this.fail({ error: err });
|
|
552
592
|
}
|
|
553
593
|
}
|
|
554
594
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/utils/layer.ts", "../src/utils/precision.ts", "../src/utils/setup-gl.ts", "../src/lifecycle-test.ts", "../src/generate-layer-tests.ts", "../src/test-runner.ts", "../src/utils/dom.ts", "../src/snapshot-test-runner.ts", "../src/interaction-test-runner.ts"],
|
|
4
|
-
"sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport {getLayerUniforms} from './utils/layer';\nexport {toLowPrecision} from './utils/precision';\nexport {gl, device} from './utils/setup-gl';\n\n// Utilities for update tests (lifecycle tests)\nexport {\n testLayer,\n testLayerAsync,\n testInitializeLayer,\n testInitializeLayerAsync\n} from './lifecycle-test';\nexport {generateLayerTests} from './generate-layer-tests';\n\n// Basic utility for rendering multiple scenes (could go into \"deck.gl/core\")\nexport {TestRunner} from './test-runner';\n\n// A utility that renders a list of scenes and compares against golden images\nexport {SnapshotTestRunner} from './snapshot-test-runner';\n// A utility that emulates input events\nexport {InteractionTestRunner} from './interaction-test-runner';\n\nexport type {LayerTestCase} from './lifecycle-test';\nexport type {SnapshotTestCase} from './snapshot-test-runner';\nexport type {InteractionTestCase} from './interaction-test-runner';\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {UniformValue} from '@luma.gl/core';\nimport {Layer} from '@deck.gl/core';\n\n/**\n * Extract uniform values set for a Layer in the underlying UniformBlock store\n */\nexport function getLayerUniforms(layer: Layer, blockName?: string): Record<string, UniformValue> {\n const uniforms = {};\n const uniformStore = layer.getModels()[0]._uniformStore;\n const uniformBlocks = blockName\n ? [uniformStore.uniformBlocks.get(blockName)]\n : uniformStore.uniformBlocks.values();\n for (const block of uniformBlocks) {\n Object.assign(uniforms, block!.uniforms);\n }\n\n return uniforms;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport function toLowPrecision(input: number, precision?: number): number;\nexport function toLowPrecision(input: number[], precision?: number): number[];\nexport function toLowPrecision(\n input: Record<string, number>,\n precision?: number\n): Record<string, number>;\n\n/**\n * Covert all numbers in a deep structure to a given precision, allowing\n * reliable float comparisons. Converts data in-place.\n */\nexport function toLowPrecision(\n input: number | number[] | Record<string, number>,\n precision: number = 11\n): number | number[] | Record<string, number> {\n /* eslint-disable guard-for-in */\n if (typeof input === 'number') {\n return Number(input.toPrecision(precision));\n }\n if (Array.isArray(input)) {\n return input.map(item => toLowPrecision(item, precision));\n }\n if (typeof input === 'object') {\n for (const key in input) {\n input[key] = toLowPrecision(input[key], precision);\n }\n }\n return input;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {CanvasContextProps} from '@luma.gl/core';\nimport {WebGLDevice} from '@luma.gl/webgl';\nimport {webglDevice, NullDevice} from '@luma.gl/test-utils';\n\nexport const device = webglDevice || new NullDevice({});\nexport const gl = webglDevice?.gl || 1;\n\nglobalThis.glContext = globalThis.glContext || gl;\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {LayerManager, MapView, DeckRenderer} from '@deck.gl/core';\n\nimport {makeSpy} from '@probe.gl/test-utils';\nimport {device} from './utils/setup-gl';\n\nimport type {Layer, CompositeLayer, Viewport} from '@deck.gl/core';\nimport type {Timeline} from '@luma.gl/engine';\nimport type {StatsManager} from '@luma.gl/core';\n\nconst testViewport = new MapView({}).makeViewport({\n width: 100,\n height: 100,\n viewState: {longitude: 0, latitude: 0, zoom: 1}\n}) as Viewport;\n\nfunction defaultOnError(error: unknown, title: string): void {\n if (error) {\n throw error;\n }\n}\n\ntype InitializeLayerTestOptions = {\n /** The layer instance to test */\n layer: Layer;\n /** The initial viewport\n * @default WebMercatorViewport\n */\n viewport?: Viewport;\n /** Callback if any error is thrown */\n onError?: (error: unknown, title: string) => void;\n};\n\nfunction initializeLayerManager({\n layer,\n viewport = testViewport,\n onError = defaultOnError\n}: InitializeLayerTestOptions): LayerManager {\n const layerManager = new LayerManager(device, {viewport});\n layerManager.setProps({\n onError: error => onError(error, `initializing ${layer.id}`)\n });\n\n layerManager.setLayers([layer]);\n return layerManager;\n}\n\n/** Test that initializing a layer does not throw.\n * Use `testInitializeLayerAsync` if the layer's initialization flow contains async operations.\n */\nexport function testInitializeLayer(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: true;\n }\n): null;\nexport function testInitializeLayer(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize: false;\n }\n): {\n /** Finalize the layer and release all resources */\n finalize: () => void;\n};\n\nexport function testInitializeLayer(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: boolean;\n }\n): {\n /** Finalize the layer and release all resources */\n finalize: () => void;\n} | null {\n const layerManager = initializeLayerManager(opts);\n if (opts.finalize === false) {\n return {\n finalize: () => layerManager.finalize()\n };\n }\n layerManager.finalize();\n return null;\n}\n\n/** Test that initializing a layer does not throw.\n * Resolves when the layer's isLoaded flag becomes true.\n */\nexport function testInitializeLayerAsync(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: true;\n }\n): Promise<null>;\nexport function testInitializeLayerAsync(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize: false;\n }\n): Promise<{\n /** Finalize the layer and release all resources */\n finalize: () => void;\n}>;\n\nexport async function testInitializeLayerAsync(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: boolean;\n }\n): Promise<{\n /** Finalize the layer and release all resources */\n finalize: () => void;\n} | null> {\n const layerManager = initializeLayerManager(opts);\n const deckRenderer = new DeckRenderer(device);\n while (!opts.layer.isLoaded) {\n await update({layerManager, deckRenderer, oldResourceCounts: {}});\n }\n if (opts.finalize === false) {\n return {\n finalize: () => layerManager.finalize()\n };\n }\n layerManager.finalize();\n return null;\n}\n\n// TODO - export from probe.gl\ntype Spy = ReturnType<typeof makeSpy>;\n\nexport type LayerClass<LayerT extends Layer> = {\n new (...args): LayerT;\n layerName: string;\n defaultProps: any;\n};\n\nexport type LayerTestCase<LayerT extends Layer> = {\n title: string;\n viewport?: Viewport;\n /** Reset the props of the test layer instance */\n props?: Partial<LayerT['props']>;\n /** Update the given props of the test layer instance */\n updateProps?: Partial<LayerT['props']>;\n /** List of layer method names to watch */\n spies?: string[];\n\n /** Called before layer updates */\n onBeforeUpdate?: (params: {layer: Layer; testCase: LayerTestCase<LayerT>}) => void;\n\n /** Called after layer is updated */\n onAfterUpdate?: (params: {\n testCase: LayerTestCase<LayerT>;\n layer: LayerT;\n oldState: any;\n subLayers: Layer[];\n subLayer: Layer | null;\n spies: Record<string, Spy>;\n }) => void;\n};\n\ntype TestResources = {\n layerManager: LayerManager;\n deckRenderer: DeckRenderer;\n oldResourceCounts: Record<string, number>;\n};\n\n/**\n * Initialize and updates a layer over a sequence of scenarios (test cases).\n * Use `testLayerAsync` if the layer's update flow contains async operations.\n */\nexport function testLayer<LayerT extends Layer>(opts: {\n /** The layer class to test against */\n Layer: LayerClass<LayerT>;\n /** The initial viewport\n * @default WebMercatorViewport\n */\n viewport?: Viewport;\n /**\n * If provided, used to controls time progression. Useful for testing transitions and animations.\n */\n timeline?: Timeline;\n testCases?: LayerTestCase<LayerT>[];\n /**\n * List of layer method names to watch\n */\n spies?: string[];\n /** Callback if any error is thrown */\n onError?: (error: Error, title: string) => void;\n}): void {\n const {Layer, testCases = [], spies = [], onError = defaultOnError} = opts;\n\n const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);\n\n let layer = new Layer();\n // Run successive update tests\n for (const testCase of testCases) {\n // Save old state before update\n const oldState = {...layer.state};\n\n const {layer: newLayer, spyMap} = runLayerTestUpdate(testCase, resources, layer, spies);\n\n runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);\n\n // Remove spies\n Object.keys(spyMap).forEach(k => spyMap[k].reset());\n layer = newLayer;\n }\n\n const error = cleanupAfterLayerTests(resources);\n if (error) {\n onError(error, `${Layer.layerName} should delete all resources`);\n }\n}\n\n/**\n * Initialize and updates a layer over a sequence of scenarios (test cases).\n * Each test case is awaited until the layer's isLoaded flag is true.\n */\nexport async function testLayerAsync<LayerT extends Layer>(opts: {\n /** The layer class to test against */\n Layer: LayerClass<LayerT>;\n /** The initial viewport\n * @default WebMercatorViewport\n */\n viewport?: Viewport;\n /**\n * If provided, used to controls time progression. Useful for testing transitions and animations.\n */\n timeline?: Timeline;\n testCases?: LayerTestCase<LayerT>[];\n /**\n * List of layer method names to watch\n */\n spies?: string[];\n /** Callback if any error is thrown */\n onError?: (error: Error, title: string) => void;\n}): Promise<void> {\n const {Layer, testCases = [], spies = [], onError = defaultOnError} = opts;\n\n const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);\n\n let layer = new Layer();\n // Run successive update tests\n for (const testCase of testCases) {\n // Save old state before update\n const oldState = {...layer.state};\n\n const {layer: newLayer, spyMap} = runLayerTestUpdate(testCase, resources, layer, spies);\n\n runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);\n\n while (!newLayer.isLoaded) {\n await update(resources);\n runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);\n }\n\n // Remove spies\n Object.keys(spyMap).forEach(k => spyMap[k].reset());\n layer = newLayer;\n }\n\n const error = cleanupAfterLayerTests(resources);\n if (error) {\n onError(error, `${Layer.layerName} should delete all resources`);\n }\n}\n\nfunction setupLayerTests(\n testTitle: string,\n {\n viewport = testViewport,\n timeline,\n onError = defaultOnError\n }: {\n viewport?: Viewport;\n timeline?: Timeline;\n onError?: (error: Error, title: string) => void;\n }\n): TestResources {\n const oldResourceCounts = getResourceCounts();\n\n const layerManager = new LayerManager(device, {viewport, timeline});\n const deckRenderer = new DeckRenderer(device);\n\n const props = {\n layerFilter: null,\n drawPickingColors: false,\n onError: error => onError(error, testTitle)\n };\n layerManager.setProps(props);\n deckRenderer.setProps(props);\n\n return {layerManager, deckRenderer, oldResourceCounts};\n}\n\nfunction cleanupAfterLayerTests({\n layerManager,\n deckRenderer,\n oldResourceCounts\n}: TestResources): Error | null {\n layerManager.setLayers([]);\n layerManager.finalize();\n deckRenderer.finalize();\n\n const resourceCounts = getResourceCounts();\n\n for (const resourceName in resourceCounts) {\n if (resourceCounts[resourceName] !== oldResourceCounts[resourceName]) {\n return new Error(\n `${resourceCounts[resourceName] - oldResourceCounts[resourceName]} ${resourceName}s`\n );\n }\n }\n return null;\n}\n\nfunction getResourceCounts(): Record<string, number> {\n /* global luma */\n const resourceStats = (luma.stats as StatsManager).get('Resource Counts');\n return {\n Texture2D: resourceStats.get('Texture2Ds Active').count,\n Buffer: resourceStats.get('Buffers Active').count\n };\n}\n\nfunction injectSpies(layer: Layer, spies: string[]): Record<string, Spy> {\n const spyMap: Record<string, Spy> = {};\n if (spies) {\n for (const functionName of spies) {\n spyMap[functionName] = makeSpy(Object.getPrototypeOf(layer), functionName);\n }\n }\n return spyMap;\n}\n\nfunction runLayerTestPostUpdateCheck<LayerT extends Layer>(\n testCase: LayerTestCase<LayerT>,\n newLayer: LayerT,\n oldState: any,\n spyMap: Record<string, Spy>\n) {\n // assert on updated layer\n if (testCase.onAfterUpdate) {\n // layer manager should handle match subLayer and tranfer state and props\n // here we assume subLayer matches copy over the new props from a new subLayer\n const subLayers = newLayer.isComposite\n ? (newLayer as Layer as CompositeLayer).getSubLayers()\n : [];\n const subLayer = subLayers.length ? subLayers[0] : null;\n\n testCase.onAfterUpdate({\n testCase,\n layer: newLayer,\n oldState,\n subLayers,\n subLayer,\n spies: spyMap\n });\n }\n}\n\nfunction runLayerTestUpdate<LayerT extends Layer>(\n testCase: LayerTestCase<LayerT>,\n {layerManager, deckRenderer}: TestResources,\n layer: LayerT,\n spies: string[]\n): {\n layer: LayerT;\n spyMap: Record<string, Spy>;\n} {\n const {props, updateProps, onBeforeUpdate, viewport = layerManager.context.viewport} = testCase;\n\n if (onBeforeUpdate) {\n onBeforeUpdate({layer, testCase});\n }\n\n if (props) {\n // Test case can reset the props on every iteration\n layer = new (layer.constructor as LayerClass<LayerT>)(props);\n } else if (updateProps) {\n // Test case can override with new props on every iteration\n layer = layer.clone(updateProps);\n }\n\n // Create a map of spies that the test case can inspect\n spies = testCase.spies || spies;\n const spyMap = injectSpies(layer, spies);\n const drawLayers = () => {\n deckRenderer.renderLayers({\n pass: 'test',\n views: {},\n effects: [],\n viewports: [viewport],\n layers: layerManager.getLayers(),\n onViewportActive: layerManager.activateViewport\n });\n };\n\n layerManager.setLayers([layer]);\n drawLayers();\n\n // clear update flags set by viewport change, if any\n if (layerManager.needsUpdate()) {\n layerManager.updateLayers();\n drawLayers();\n }\n\n return {layer, spyMap};\n}\n\n/* global setTimeout */\nfunction update({layerManager, deckRenderer}: TestResources): Promise<void> {\n return new Promise(resolve => {\n const onAnimationFrame = () => {\n if (layerManager.needsUpdate()) {\n layerManager.updateLayers();\n\n deckRenderer.renderLayers({\n pass: 'test',\n views: {},\n effects: [],\n viewports: [layerManager.context.viewport],\n layers: layerManager.getLayers(),\n onViewportActive: layerManager.activateViewport\n });\n resolve();\n return;\n }\n\n setTimeout(onAnimationFrame, 50);\n };\n\n onAnimationFrame();\n });\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {_count as count, Layer} from '@deck.gl/core';\n\nimport type {DefaultProps} from '@deck.gl/core';\nimport type {LayerTestCase, LayerClass} from './lifecycle-test';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop() {}\n\nfunction defaultAssert(condition: any, comment: string): void {\n if (!condition) {\n throw new Error(comment);\n }\n}\n\n// Automatically generate testLayer test cases\nexport function generateLayerTests<LayerT extends Layer>({\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Layer,\n sampleProps = {},\n assert = defaultAssert,\n onBeforeUpdate = noop,\n onAfterUpdate = noop,\n runDefaultAsserts = true\n}: {\n Layer: LayerClass<LayerT>;\n /**\n * Override default props during the test\n */\n sampleProps?: Partial<LayerT['props']>;\n assert?: (condition: any, comment: string) => void;\n onBeforeUpdate?: LayerTestCase<LayerT>['onBeforeUpdate'];\n onAfterUpdate?: LayerTestCase<LayerT>['onAfterUpdate'];\n\n /**\n * Test some typical assumptions after layer updates\n * For primitive layers, assert that layer has model(s).\n * For composite layers, assert that layer has sublayer(s).\n * @default true\n */\n runDefaultAsserts?: boolean;\n}): LayerTestCase<LayerT>[] {\n assert(Layer.layerName, 'Layer should have display name');\n\n function wrapTestCaseTitle(title: string): string {\n return `${Layer.layerName}#${title}`;\n }\n\n const testCases: LayerTestCase<LayerT>[] = [\n {\n title: 'Empty props',\n props: {}\n },\n {\n title: 'Null data',\n // @ts-expect-error null may not be an expected data type\n updateProps: {data: null}\n },\n {\n title: 'Sample data',\n updateProps: sampleProps\n }\n ];\n\n try {\n // Calling constructor for the first time resolves default props\n // eslint-disable-next-line\n new Layer({});\n } catch (error: unknown) {\n assert(false, `Construct ${Layer.layerName} throws: ${(error as Error).message}`);\n }\n\n // @ts-expect-error Access hidden properties\n const {_propTypes: propTypes, _mergedDefaultProps: defaultProps} = Layer;\n\n // Test alternative data formats\n testCases.push(...makeAltDataTestCases<LayerT>(sampleProps, propTypes));\n\n for (const propName in Layer.defaultProps) {\n if (!(propName in sampleProps)) {\n // Do not override user provided props - they may be layer-specific\n const newTestCase =\n makeAltPropTestCase({propName, propTypes, defaultProps, sampleProps, assert}) || [];\n testCases.push(...newTestCase);\n }\n }\n\n testCases.forEach(testCase => {\n testCase.title = wrapTestCaseTitle(testCase.title);\n const beforeFunc = testCase.onBeforeUpdate || noop;\n const afterFunc = testCase.onAfterUpdate || noop;\n testCase.onBeforeUpdate = params => {\n // Generated callback\n beforeFunc(params);\n // User callback\n onBeforeUpdate(params);\n };\n testCase.onAfterUpdate = params => {\n // Generated callback\n afterFunc(params);\n // User callback\n onAfterUpdate(params);\n\n // Default assert\n if (runDefaultAsserts) {\n if (params.layer.isComposite) {\n const {data} = params.layer.props;\n if (data && typeof data === 'object' && count(data)) {\n assert(params.subLayers.length, 'Layer should have sublayers');\n }\n } else {\n assert(params.layer.getModels().length, 'Layer should have models');\n }\n }\n };\n });\n\n return testCases;\n}\n\nfunction makeAltPropTestCase<LayerT extends Layer>({\n propName,\n propTypes,\n defaultProps,\n sampleProps,\n assert\n}: {\n propName: string;\n propTypes: DefaultProps<LayerT['props']>;\n defaultProps: LayerT['props'];\n sampleProps: Partial<LayerT['props']>;\n assert: (condition: any, comment: string) => void;\n}): LayerTestCase<LayerT>[] | null {\n const newProps = {...sampleProps};\n const propDef = propTypes[propName];\n\n if (!propDef) {\n return null;\n }\n\n switch (propDef.type) {\n case 'boolean':\n newProps[propName] = !defaultProps[propName];\n return [\n {\n title: `${propName}: ${String(newProps[propName])}`,\n props: newProps\n }\n ];\n\n case 'number':\n if ('max' in propDef) {\n newProps[propName] = propDef.max;\n } else if ('min' in propDef) {\n newProps[propName] = propDef.min;\n } else {\n newProps[propName] = defaultProps[propName] + 1;\n }\n return [\n {\n title: `${propName}: ${String(newProps[propName])}`,\n props: newProps\n }\n ];\n\n case 'accessor': {\n if (typeof defaultProps[propName] === 'function') {\n return null;\n }\n let callCount = 0;\n newProps[propName] = () => {\n callCount++;\n return defaultProps[propName];\n };\n newProps.updateTriggers = {\n [propName]: 'function'\n };\n const onBeforeUpdate = () => (callCount = 0);\n const onAfterUpdate = () => assert(callCount > 0, 'accessor function is called');\n\n return [\n {\n title: `${propName}: () => ${defaultProps[propName]}`,\n props: newProps,\n onBeforeUpdate,\n onAfterUpdate\n },\n {\n title: `${propName}: updateTrigger`,\n updateProps: {\n updateTriggers: {\n [propName]: 'function+trigger'\n }\n } as Partial<Layer['props']>,\n onBeforeUpdate,\n onAfterUpdate\n }\n ];\n }\n\n default:\n return null;\n }\n}\n\nfunction makeAltDataTestCases<LayerT extends Layer>(\n props: Partial<LayerT['props']>,\n propTypes: DefaultProps<LayerT['props']>\n): LayerTestCase<LayerT>[] {\n const originalData = props.data;\n if (!Array.isArray(originalData)) {\n return [];\n }\n // partial update\n const partialUpdateProps: Partial<Layer['props']> = {\n data: originalData.slice(),\n _dataDiff: () => [{startRow: 0, endRow: 2}]\n };\n // data should support any iterable\n const genIterableProps: Partial<Layer['props']> = {\n data: new Set(originalData),\n _dataDiff: null\n };\n // data in non-iterable form\n const nonIterableProps: Partial<Layer['props']> = {\n data: {\n length: originalData.length\n }\n };\n for (const propName in props) {\n // @ts-ignore propName cannot be used as index\n if (propTypes[propName].type === 'accessor') {\n // @ts-ignore propName cannot be used as index\n nonIterableProps[propName] = (_, info) => props[propName](originalData[info.index], info);\n }\n }\n\n return [\n {\n title: 'Partial update',\n updateProps: partialUpdateProps\n },\n {\n title: 'Generic iterable data',\n updateProps: genIterableProps\n },\n {\n title: 'non-iterable data',\n updateProps: nonIterableProps\n }\n ];\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window, console, setTimeout */\n/* eslint-disable no-console */\nimport {Deck, DeckProps, MapView} from '@deck.gl/core';\nimport type {Device} from '@luma.gl/core';\n\nconst DEFAULT_DECK_PROPS: DeckProps<any> = {\n ...Deck.defaultProps,\n id: 'deckgl-render-test',\n width: 800,\n height: 450,\n style: {position: 'absolute', left: '0px', top: '0px'},\n views: [new MapView({})],\n useDevicePixels: false,\n debug: true\n};\n\nexport type TestCase = {\n name: string;\n /** milliseconds to wait before aborting */\n timeout?: number;\n};\n\ntype TestOptions<TestCaseT extends TestCase, ResultT> = {\n /** Called when a test case starts */\n onTestStart: (testCase: TestCaseT) => void;\n /** Called when a test case passes */\n onTestPass: (testCase: TestCaseT, result: ResultT) => void;\n /** Called when a test case fails */\n onTestFail: (testCase: TestCaseT, result: ResultT | {error: string}) => void;\n\n /** milliseconds to wait for each test case before aborting */\n timeout: number;\n};\n\nconst DEFAULT_TEST_OPTIONS: TestOptions<TestCase, unknown> = {\n // test lifecycle callback\n onTestStart: testCase => console.log(`# ${testCase.name}`),\n onTestPass: testCase => console.log(`ok ${testCase.name} passed`),\n onTestFail: testCase => console.log(`not ok ${testCase.name} failed`),\n\n // milliseconds to wait for each test case before aborting\n timeout: 2000\n};\n\nexport abstract class TestRunner<TestCaseT extends TestCase, ResultT, ExtraOptions = {}> {\n deck: Deck<any> | null = null;\n props: DeckProps<any>;\n isHeadless: boolean;\n isRunning: boolean = false;\n testOptions: TestOptions<TestCaseT, ResultT> & ExtraOptions;\n gpuVendor?: string;\n\n private _testCases: TestCaseT[] = [];\n private _currentTestCase: TestCaseT | null = null;\n private _testCaseData: unknown = null;\n\n /**\n * props\n * Deck props\n */\n constructor(props: DeckProps = {}, options: ExtraOptions) {\n this.props = {...DEFAULT_DECK_PROPS, ...props};\n\n // @ts-ignore browserTestDriver_isHeadless is injected by @probe.gl/test-utils if running in headless browser\n this.isHeadless = Boolean(window.browserTestDriver_isHeadless);\n\n this.testOptions = {...DEFAULT_TEST_OPTIONS, ...options};\n }\n\n get defaultTestCase(): TestCaseT {\n throw new Error('Not implemented');\n }\n\n /**\n * Add testCase(s)\n */\n add(testCases: TestCaseT[]): this {\n if (!Array.isArray(testCases)) {\n testCases = [testCases];\n }\n for (const testCase of testCases) {\n this._testCases.push(testCase);\n }\n return this;\n }\n\n /**\n * Returns a promise that resolves when all the test cases are done\n */\n run(options: Partial<TestOptions<TestCaseT, ResultT> & ExtraOptions> = {}): Promise<void> {\n Object.assign(this.testOptions, options);\n\n return new Promise<void>((resolve, reject) => {\n this.deck = new Deck({\n ...this.props,\n onDeviceInitialized: this._onDeviceInitialized.bind(this),\n onLoad: resolve\n });\n\n this.isRunning = true;\n this._currentTestCase = null;\n })\n .then(() => {\n let promise = Promise.resolve();\n // chain test case promises\n this._testCases.forEach(testCase => {\n promise = promise.then(() => this._runTest(testCase));\n });\n return promise;\n })\n .catch((error: unknown) => {\n this.fail({error: (error as Error).message});\n })\n .finally(() => {\n this.deck!.finalize();\n this.deck = null;\n });\n }\n\n /* Lifecycle methods for subclassing */\n\n initTestCase(testCase: TestCaseT) {\n for (const key in this.defaultTestCase) {\n if (!(key in testCase)) {\n testCase[key] = this.defaultTestCase[key];\n }\n }\n this.testOptions.onTestStart(testCase);\n }\n\n /** Execute the test case. Fails if takes longer than options.timeout */\n abstract runTestCase(testCase: TestCaseT): Promise<void>;\n /** Check the result of the test case. Calls pass() or fail() */\n abstract assert(testCase: TestCaseT): Promise<void>;\n\n /* Utilities */\n\n protected pass(result: ResultT) {\n this.testOptions.onTestPass(this._currentTestCase!, result);\n }\n\n protected fail(result: ResultT | {error: string}) {\n this.testOptions.onTestFail(this._currentTestCase!, result);\n }\n\n /* Private Methods */\n\n private _onDeviceInitialized(device: Device) {\n this.gpuVendor = device.info.vendor;\n }\n\n private async _runTest(testCase: TestCaseT) {\n this._currentTestCase = testCase;\n\n // normalize test case\n this.initTestCase(testCase);\n\n const timeout = testCase.timeout || this.testOptions.timeout;\n const task = this.runTestCase(testCase);\n const timeoutTask = new Promise((_, reject) => {\n setTimeout(() => {\n reject('Timeout');\n }, timeout);\n });\n\n try {\n await Promise.race([task, timeoutTask]);\n await this.assert(testCase);\n } catch (err: unknown) {\n if (err === 'Timeout') {\n this.fail({error: 'Timeout'});\n }\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window */\n// Get the bounding box of a DOMElement relative to the page\nexport function getBoundingBoxInPage(domElement: HTMLElement): {\n x: number;\n y: number;\n width: number;\n height: number;\n} {\n const bbox = domElement.getBoundingClientRect();\n return {\n x: window.scrollX + bbox.x,\n y: window.scrollY + bbox.y,\n width: bbox.width,\n height: bbox.height\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window */\nimport {TestRunner} from './test-runner';\nimport {getBoundingBoxInPage} from './utils/dom';\n\nimport type {DeckProps, Deck, Layer} from '@deck.gl/core';\n\n// TODO - export from probe.gl\ntype ImageDiffOptions = {\n saveOnFail?: boolean;\n saveAs?: string;\n threshold?: number; // 0.99,\n createDiffImage?: boolean; // false,\n tolerance?: number; // 0.1,\n includeAA?: boolean; // false,\n includeEmpty?: boolean; // true\n platform?: string;\n};\n\ntype DiffImageResult = {\n headless: boolean;\n match: string | number;\n matchPercentage: string;\n success: boolean;\n error: Error | string | null;\n};\n\nexport type SnapshotTestCase = {\n name: string;\n props: DeckProps;\n goldenImage: string;\n onBeforeRender?: (params: {deck: Deck; layers: Layer[]}) => void;\n onAfterRender?: (params: {deck: Deck; layers: Layer[]; done: () => void}) => void;\n timeout?: number;\n imageDiffOptions?: ImageDiffOptions;\n};\n\nconst DEFAULT_TEST_OPTIONS = {\n imageDiffOptions: {}\n};\n\nconst DEFAULT_TEST_CASE: SnapshotTestCase = {\n name: 'Unnamed snapshot test',\n props: {},\n onBeforeRender: ({deck, layers}) => {\n // eslint-disable-line\n },\n onAfterRender: ({deck, layers, done}) => {\n if (\n // @ts-expect-error accessing private\n !deck.layerManager?.needsUpdate() &&\n layers.every(layer => layer.isLoaded)\n ) {\n done(); // eslint-disable-line\n }\n },\n goldenImage: ''\n};\n\nexport class SnapshotTestRunner extends TestRunner<\n SnapshotTestCase,\n DiffImageResult,\n {imageDiffOptions: ImageDiffOptions}\n> {\n private _isDiffing: boolean = false;\n\n constructor(props) {\n super(props, DEFAULT_TEST_OPTIONS);\n\n this._isDiffing = false;\n }\n\n get defaultTestCase() {\n return DEFAULT_TEST_CASE;\n }\n\n initTestCase(testCase: SnapshotTestCase) {\n super.initTestCase(testCase);\n if (!testCase.goldenImage) {\n throw new Error(`Test case ${testCase.name} does not have golden image`);\n }\n }\n\n runTestCase(testCase: SnapshotTestCase) {\n const deck = this.deck!;\n\n return new Promise<void>(resolve => {\n deck.setProps({\n ...this.props,\n ...testCase,\n onBeforeRender: () => {\n testCase.onBeforeRender!({\n deck,\n // @ts-expect-error Accessing protected layerManager\n layers: this.deck.layerManager.getLayers()\n });\n },\n onAfterRender: () => {\n testCase.onAfterRender!({\n deck,\n // @ts-expect-error Accessing protected layerManager\n layers: this.deck.layerManager.getLayers(),\n done: resolve\n });\n }\n });\n });\n }\n\n async assert(testCase: SnapshotTestCase) {\n if (this._isDiffing) {\n // already performing diffing\n return;\n }\n this._isDiffing = true;\n\n const diffOptions = {\n ...this.testOptions.imageDiffOptions,\n ...testCase.imageDiffOptions,\n goldenImage: testCase.goldenImage,\n region: getBoundingBoxInPage(this.deck!.getCanvas()!)\n };\n // Take screenshot and compare\n const result = await window.browserTestDriver_captureAndDiffScreen(diffOptions);\n\n // If failed, try if we have a platform specific golden image\n let resultOverride;\n const platform = this.testOptions.imageDiffOptions?.platform?.toLowerCase();\n if (!result.success) {\n diffOptions.goldenImage = diffOptions.goldenImage.replace(\n 'golden-images/',\n `golden-images/platform-overrides/${platform}/`\n );\n resultOverride = await window.browserTestDriver_captureAndDiffScreen(diffOptions);\n }\n\n // invoke user callback\n if (result.success || resultOverride.success) {\n this.pass(result);\n } else {\n this.fail(result);\n }\n\n this._isDiffing = false;\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window */\nimport {TestRunner} from './test-runner';\nimport type {Deck, Layer} from '@deck.gl/core';\n\ntype InteractionEvent =\n | {\n type: string;\n [key: string]: any;\n }\n | {\n wait: number;\n };\n\nexport type InteractionTestCase = {\n name: string;\n events: InteractionEvent[];\n timeout?: number;\n context?: any;\n onBeforeEvents: (params: {deck: Deck}) => any;\n onAfterEvents: (params: {deck: Deck; layers: Layer[]; context: any}) => void;\n};\n\nconst DEFAULT_TEST_CASE: InteractionTestCase = {\n name: 'Unnamed interaction test',\n events: [],\n onBeforeEvents: ({deck}) => {},\n onAfterEvents: ({deck, layers, context}) => {}\n};\n\nfunction sleep(timeout: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, timeout));\n}\n\nexport class InteractionTestRunner extends TestRunner<InteractionTestCase, {}> {\n get defaultTestCase() {\n return DEFAULT_TEST_CASE;\n }\n\n // chain events\n async runTestCase(testCase: InteractionTestCase) {\n testCase.context = testCase.onBeforeEvents({\n deck: this.deck!\n });\n\n for (const event of testCase.events) {\n if (event.wait) {\n await sleep(event.wait);\n } else {\n await window.browserTestDriver_emulateInput(event);\n }\n }\n }\n\n async assert(testCase) {\n testCase.onAfterEvents({\n deck: this.deck,\n // @ts-expect-error Accessing protected layerManager\n layers: this.deck.layerManager.getLayers(),\n context: testCase.context\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["import_test_utils", "import_core", "count", "import_core", "device", "DEFAULT_TEST_OPTIONS", "_a", "DEFAULT_TEST_CASE"]
|
|
3
|
+
"sources": ["../src/index.ts", "../src/utils/layer.ts", "../src/utils/precision.ts", "../src/utils/setup-gl.ts", "../src/tape.ts", "../src/lifecycle-test.ts", "../src/generate-layer-tests.ts", "../src/test-runner.ts", "../src/utils/dom.ts", "../src/snapshot-test-runner.ts", "../src/interaction-test-runner.ts"],
|
|
4
|
+
"sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport {getLayerUniforms} from './utils/layer';\nexport {toLowPrecision} from './utils/precision';\nexport {gl, device} from './utils/setup-gl';\n\n// Utilities for update tests (lifecycle tests)\n// Re-export from tape.ts which provides default spy factory for backward compat\nexport {testLayer, testLayerAsync, testInitializeLayer, testInitializeLayerAsync} from './tape';\nexport {generateLayerTests} from './generate-layer-tests';\n\n// Basic utility for rendering multiple scenes (could go into \"deck.gl/core\")\nexport {TestRunner} from './test-runner';\n\n// A utility that renders a list of scenes and compares against golden images\nexport {SnapshotTestRunner} from './snapshot-test-runner';\n// A utility that emulates input events\nexport {InteractionTestRunner} from './interaction-test-runner';\n\nexport type {LayerTestCase, ResetSpy, SpyFactory} from './tape';\nexport type {SnapshotTestCase} from './snapshot-test-runner';\nexport type {InteractionTestCase} from './interaction-test-runner';\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {UniformValue} from '@luma.gl/core';\nimport {Layer} from '@deck.gl/core';\n\n/**\n * Extract uniform values set for a Layer in the underlying UniformBlock store\n */\nexport function getLayerUniforms(layer: Layer, blockName?: string): Record<string, UniformValue> {\n const uniforms = {};\n const uniformStore = layer.getModels()[0]._uniformStore;\n const uniformBlocks = blockName\n ? [uniformStore.uniformBlocks.get(blockName)]\n : uniformStore.uniformBlocks.values();\n for (const block of uniformBlocks) {\n Object.assign(uniforms, block!.uniforms);\n }\n\n return uniforms;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport function toLowPrecision(input: number, precision?: number): number;\nexport function toLowPrecision(input: number[], precision?: number): number[];\nexport function toLowPrecision(\n input: Record<string, number>,\n precision?: number\n): Record<string, number>;\n\n/**\n * Covert all numbers in a deep structure to a given precision, allowing\n * reliable float comparisons. Converts data in-place.\n */\nexport function toLowPrecision(\n input: number | number[] | Record<string, number>,\n precision: number = 11\n): number | number[] | Record<string, number> {\n /* eslint-disable guard-for-in */\n if (typeof input === 'number') {\n return Number(input.toPrecision(precision));\n }\n if (Array.isArray(input)) {\n return input.map(item => toLowPrecision(item, precision));\n }\n if (typeof input === 'object') {\n for (const key in input) {\n input[key] = toLowPrecision(input[key], precision);\n }\n }\n return input;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {webglDevice, NullDevice} from '@luma.gl/test-utils';\n\n// Use pre-created device from @luma.gl/test-utils, fall back to NullDevice in Node\nexport const device = webglDevice || new NullDevice({});\nexport const gl = webglDevice?.gl || 1;\n\nglobalThis.glContext = globalThis.glContext || gl;\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Tape entry point - wraps lifecycle-test and adds @probe.gl/test-utils as the default spy factory\n// For vitest users, use @deck.gl/test-utils/vitest which doesn't import probe.gl\n\nimport {makeSpy} from '@probe.gl/test-utils';\nimport {\n testLayer as testLayerCore,\n testLayerAsync as testLayerAsyncCore,\n testInitializeLayer,\n testInitializeLayerAsync\n} from './lifecycle-test';\nimport type {Layer} from '@deck.gl/core';\nimport type {\n LayerClass,\n LayerTestCase,\n ResetSpy,\n SpyFactory,\n TestLayerOptions\n} from './lifecycle-test';\n\nexport {testInitializeLayer, testInitializeLayerAsync};\nexport type {LayerClass, LayerTestCase, ResetSpy, SpyFactory};\n\nlet _hasWarnedCreateSpy = false;\nlet _hasWarnedResetSpy = false;\n\nfunction getDefaultSpyFactory(): SpyFactory {\n if (!_hasWarnedCreateSpy) {\n _hasWarnedCreateSpy = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@deck.gl/test-utils] Implicit @probe.gl/test-utils usage is deprecated. ' +\n 'Pass createSpy option: createSpy: (obj, method) => vi.spyOn(obj, method) for vitest, ' +\n 'or createSpy: makeSpy for probe.gl.'\n );\n }\n return makeSpy;\n}\n\n/** Default reset for probe.gl spies - clears call tracking but keeps spy active */\nfunction getDefaultResetSpy(): ResetSpy {\n if (!_hasWarnedResetSpy) {\n _hasWarnedResetSpy = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@deck.gl/test-utils] Implicit spy reset is deprecated. ' +\n 'Pass resetSpy option: resetSpy: (spy) => spy.mockRestore() for vitest, ' +\n 'or resetSpy: (spy) => spy.reset() for probe.gl.'\n );\n }\n return spy => (spy as ReturnType<typeof makeSpy>).reset();\n}\n\n/**\n * Initialize and updates a layer over a sequence of scenarios (test cases).\n * Use `testLayerAsync` if the layer's update flow contains async operations.\n */\nexport function testLayer<LayerT extends Layer>(\n opts: Omit<TestLayerOptions<LayerT>, 'createSpy' | 'resetSpy'> & {\n createSpy?: SpyFactory;\n resetSpy?: ResetSpy;\n }\n): void {\n const createSpy = opts.createSpy || getDefaultSpyFactory();\n const resetSpy = opts.resetSpy || getDefaultResetSpy();\n testLayerCore({...opts, createSpy, resetSpy});\n}\n\n/**\n * Initialize and updates a layer over a sequence of scenarios (test cases).\n * Each test case is awaited until the layer's isLoaded flag is true.\n */\nexport async function testLayerAsync<LayerT extends Layer>(\n opts: Omit<TestLayerOptions<LayerT>, 'createSpy' | 'resetSpy'> & {\n createSpy?: SpyFactory;\n resetSpy?: ResetSpy;\n }\n): Promise<void> {\n const createSpy = opts.createSpy || getDefaultSpyFactory();\n const resetSpy = opts.resetSpy || getDefaultResetSpy();\n await testLayerAsyncCore({...opts, createSpy, resetSpy});\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {LayerManager, MapView, DeckRenderer} from '@deck.gl/core';\n\nimport {device} from './utils/setup-gl';\n\nimport type {Layer, CompositeLayer, Viewport} from '@deck.gl/core';\nimport type {Timeline} from '@luma.gl/engine';\nimport type {StatsManager} from '@luma.gl/core';\n\nconst testViewport = new MapView({}).makeViewport({\n width: 100,\n height: 100,\n viewState: {longitude: 0, latitude: 0, zoom: 1}\n}) as Viewport;\n\nfunction defaultOnError(error: unknown, title: string): void {\n if (error) {\n throw error;\n }\n}\n\ntype InitializeLayerTestOptions = {\n /** The layer instance to test */\n layer: Layer;\n /** The initial viewport\n * @default WebMercatorViewport\n */\n viewport?: Viewport;\n /** Callback if any error is thrown */\n onError?: (error: unknown, title: string) => void;\n};\n\nfunction initializeLayerManager({\n layer,\n viewport = testViewport,\n onError = defaultOnError\n}: InitializeLayerTestOptions): LayerManager {\n const layerManager = new LayerManager(device, {viewport});\n layerManager.setProps({\n onError: error => onError(error, `initializing ${layer.id}`)\n });\n\n layerManager.setLayers([layer]);\n return layerManager;\n}\n\n/** Test that initializing a layer does not throw.\n * Use `testInitializeLayerAsync` if the layer's initialization flow contains async operations.\n */\nexport function testInitializeLayer(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: true;\n }\n): null;\nexport function testInitializeLayer(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize: false;\n }\n): {\n /** Finalize the layer and release all resources */\n finalize: () => void;\n};\n\nexport function testInitializeLayer(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: boolean;\n }\n): {\n /** Finalize the layer and release all resources */\n finalize: () => void;\n} | null {\n const layerManager = initializeLayerManager(opts);\n if (opts.finalize === false) {\n return {\n finalize: () => layerManager.finalize()\n };\n }\n layerManager.finalize();\n return null;\n}\n\n/** Test that initializing a layer does not throw.\n * Resolves when the layer's isLoaded flag becomes true.\n */\nexport function testInitializeLayerAsync(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: true;\n }\n): Promise<null>;\nexport function testInitializeLayerAsync(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize: false;\n }\n): Promise<{\n /** Finalize the layer and release all resources */\n finalize: () => void;\n}>;\n\nexport async function testInitializeLayerAsync(\n opts: InitializeLayerTestOptions & {\n /** Automatically finalize the layer and release all resources after the test */\n finalize?: boolean;\n }\n): Promise<{\n /** Finalize the layer and release all resources */\n finalize: () => void;\n} | null> {\n const layerManager = initializeLayerManager(opts);\n const deckRenderer = new DeckRenderer(device);\n while (!opts.layer.isLoaded) {\n await update({layerManager, deckRenderer, oldResourceCounts: {}});\n }\n if (opts.finalize === false) {\n return {\n finalize: () => layerManager.finalize()\n };\n }\n layerManager.finalize();\n return null;\n}\n\n/** Spy object compatible with both vitest and probe.gl */\nexport type Spy = {\n /** Restore the original method (vitest) */\n mockRestore?: () => void;\n /** Restore the original method (probe.gl) */\n restore?: () => void;\n /** Call history (vitest) */\n mock?: {calls: unknown[][]};\n /** Call history (probe.gl) */\n calls?: unknown[][];\n /** Whether the spy was called (probe.gl) */\n called?: boolean;\n};\n\n/** Factory function to create a spy on an object method */\nexport type SpyFactory = (obj: object, method: string) => Spy;\n\n/** Function to reset/cleanup a spy after each test case */\nexport type ResetSpy = (spy: Spy) => void;\n\nexport type LayerClass<LayerT extends Layer> = {\n new (...args): LayerT;\n layerName: string;\n defaultProps: any;\n};\n\nexport type LayerTestCase<LayerT extends Layer> = {\n title: string;\n viewport?: Viewport;\n /** Reset the props of the test layer instance */\n props?: Partial<LayerT['props']>;\n /** Update the given props of the test layer instance */\n updateProps?: Partial<LayerT['props']>;\n /** List of layer method names to watch */\n spies?: string[];\n\n /** Called before layer updates */\n onBeforeUpdate?: (params: {layer: Layer; testCase: LayerTestCase<LayerT>}) => void;\n\n /** Called after layer is updated */\n onAfterUpdate?: (params: {\n testCase: LayerTestCase<LayerT>;\n layer: LayerT;\n oldState: any;\n subLayers: Layer[];\n subLayer: Layer | null;\n spies: Record<string, Spy>;\n }) => void;\n};\n\ntype TestResources = {\n layerManager: LayerManager;\n deckRenderer: DeckRenderer;\n oldResourceCounts: Record<string, number>;\n};\n\nexport type TestLayerOptions<LayerT extends Layer> = {\n /** The layer class to test against */\n Layer: LayerClass<LayerT>;\n /** The initial viewport\n * @default WebMercatorViewport\n */\n viewport?: Viewport;\n /**\n * If provided, used to controls time progression. Useful for testing transitions and animations.\n */\n timeline?: Timeline;\n testCases?: LayerTestCase<LayerT>[];\n /**\n * List of layer method names to watch\n */\n spies?: string[];\n /** Callback if any error is thrown */\n onError?: (error: Error, title: string) => void;\n /** Factory function to create spies */\n createSpy: SpyFactory;\n /** Function to reset/cleanup a spy after each test case */\n resetSpy: ResetSpy;\n};\n\n/**\n * Initialize and updates a layer over a sequence of scenarios (test cases).\n * Use `testLayerAsync` if the layer's update flow contains async operations.\n */\nexport function testLayer<LayerT extends Layer>(opts: TestLayerOptions<LayerT>): void {\n const {Layer, testCases = [], spies = [], onError = defaultOnError, createSpy, resetSpy} = opts;\n\n const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);\n\n let layer = new Layer();\n // Run successive update tests\n for (const testCase of testCases) {\n // Save old state before update\n const oldState = {...layer.state};\n\n const {layer: newLayer, spyMap} = runLayerTestUpdate(\n testCase,\n resources,\n layer,\n spies,\n createSpy\n );\n\n runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);\n\n // Reset spies between test cases\n Object.keys(spyMap).forEach(k => resetSpy(spyMap[k]));\n layer = newLayer;\n }\n\n const error = cleanupAfterLayerTests(resources);\n if (error) {\n onError(error, `${Layer.layerName} should delete all resources`);\n }\n}\n\n/**\n * Initialize and updates a layer over a sequence of scenarios (test cases).\n * Each test case is awaited until the layer's isLoaded flag is true.\n */\nexport async function testLayerAsync<LayerT extends Layer>(\n opts: TestLayerOptions<LayerT>\n): Promise<void> {\n const {Layer, testCases = [], spies = [], onError = defaultOnError, createSpy, resetSpy} = opts;\n\n const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);\n\n let layer = new Layer();\n // Run successive update tests\n for (const testCase of testCases) {\n // Save old state before update\n const oldState = {...layer.state};\n\n const {layer: newLayer, spyMap} = runLayerTestUpdate(\n testCase,\n resources,\n layer,\n spies,\n createSpy\n );\n\n runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);\n\n while (!newLayer.isLoaded) {\n await update(resources);\n runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);\n }\n\n // Reset spies between test cases\n Object.keys(spyMap).forEach(k => resetSpy(spyMap[k]));\n layer = newLayer;\n }\n\n // Use async cleanup to allow pending luma.gl async operations to complete\n const error = await cleanupAfterLayerTestsAsync(resources);\n if (error) {\n onError(error, `${Layer.layerName} should delete all resources`);\n }\n}\n\nfunction setupLayerTests(\n testTitle: string,\n {\n viewport = testViewport,\n timeline,\n onError = defaultOnError\n }: {\n viewport?: Viewport;\n timeline?: Timeline;\n onError?: (error: Error, title: string) => void;\n }\n): TestResources {\n const oldResourceCounts = getResourceCounts();\n\n const layerManager = new LayerManager(device, {viewport, timeline});\n const deckRenderer = new DeckRenderer(device);\n\n const props = {\n layerFilter: null,\n drawPickingColors: false,\n onError: error => onError(error, testTitle)\n };\n layerManager.setProps(props);\n deckRenderer.setProps(props);\n\n return {layerManager, deckRenderer, oldResourceCounts};\n}\n\nfunction cleanupAfterLayerTests({\n layerManager,\n deckRenderer,\n oldResourceCounts\n}: TestResources): Error | null {\n layerManager.setLayers([]);\n layerManager.finalize();\n deckRenderer.finalize();\n\n return getResourceCountDelta(oldResourceCounts);\n}\n\n/**\n * Async cleanup that waits for pending async operations before finalizing resources.\n * This prevents unhandled rejections from luma.gl's async shader error reporting\n * which may try to access destroyed WebGL resources if cleanup happens too early.\n */\nasync function cleanupAfterLayerTestsAsync({\n layerManager,\n deckRenderer,\n oldResourceCounts\n}: TestResources): Promise<Error | null> {\n layerManager.setLayers([]);\n\n // Wait for any pending async operations (e.g., luma.gl's deferred shader compilation\n // error handling) to complete before destroying resources. This prevents\n // \"getProgramInfoLog\" errors when async error reporting tries to access\n // already-destroyed WebGL programs.\n await new Promise(resolve => setTimeout(resolve, 0));\n\n layerManager.finalize();\n deckRenderer.finalize();\n\n return getResourceCountDelta(oldResourceCounts);\n}\n\nfunction getResourceCounts(): Record<string, number> {\n /* global luma */\n const resourceStats = (luma.stats as StatsManager).get('Resource Counts');\n return {\n Texture2D: resourceStats.get('Texture2Ds Active').count,\n Buffer: resourceStats.get('Buffers Active').count\n };\n}\n\nfunction getResourceCountDelta(oldResourceCounts: Record<string, number>): Error | null {\n const resourceCounts = getResourceCounts();\n\n for (const resourceName in resourceCounts) {\n if (resourceCounts[resourceName] !== oldResourceCounts[resourceName]) {\n return new Error(\n `${resourceCounts[resourceName] - oldResourceCounts[resourceName]} ${resourceName}s`\n );\n }\n }\n return null;\n}\n\nfunction injectSpies(layer: Layer, spies: string[], spyFactory: SpyFactory): Record<string, Spy> {\n const spyMap: Record<string, Spy> = {};\n if (spies) {\n for (const functionName of spies) {\n spyMap[functionName] = spyFactory(Object.getPrototypeOf(layer), functionName);\n }\n }\n return spyMap;\n}\n\nfunction runLayerTestPostUpdateCheck<LayerT extends Layer>(\n testCase: LayerTestCase<LayerT>,\n newLayer: LayerT,\n oldState: any,\n spyMap: Record<string, Spy>\n) {\n // assert on updated layer\n if (testCase.onAfterUpdate) {\n // layer manager should handle match subLayer and tranfer state and props\n // here we assume subLayer matches copy over the new props from a new subLayer\n const subLayers = newLayer.isComposite\n ? (newLayer as Layer as CompositeLayer).getSubLayers()\n : [];\n const subLayer = subLayers.length ? subLayers[0] : null;\n\n testCase.onAfterUpdate({\n testCase,\n layer: newLayer,\n oldState,\n subLayers,\n subLayer,\n spies: spyMap\n });\n }\n}\n\nfunction runLayerTestUpdate<LayerT extends Layer>(\n testCase: LayerTestCase<LayerT>,\n {layerManager, deckRenderer}: TestResources,\n layer: LayerT,\n spies: string[],\n spyFactory: SpyFactory\n): {\n layer: LayerT;\n spyMap: Record<string, Spy>;\n} {\n const {props, updateProps, onBeforeUpdate, viewport = layerManager.context.viewport} = testCase;\n\n if (onBeforeUpdate) {\n onBeforeUpdate({layer, testCase});\n }\n\n if (props) {\n // Test case can reset the props on every iteration\n layer = new (layer.constructor as LayerClass<LayerT>)(props);\n } else if (updateProps) {\n // Test case can override with new props on every iteration\n layer = layer.clone(updateProps);\n }\n\n // Create a map of spies that the test case can inspect\n spies = testCase.spies || spies;\n const spyMap = injectSpies(layer, spies, spyFactory);\n const drawLayers = () => {\n deckRenderer.renderLayers({\n pass: 'test',\n views: {},\n effects: [],\n viewports: [viewport],\n layers: layerManager.getLayers(),\n onViewportActive: layerManager.activateViewport\n });\n };\n\n layerManager.setLayers([layer]);\n drawLayers();\n\n // clear update flags set by viewport change, if any\n if (layerManager.needsUpdate()) {\n layerManager.updateLayers();\n drawLayers();\n }\n\n return {layer, spyMap};\n}\n\n/* global setTimeout */\nfunction update({layerManager, deckRenderer}: TestResources): Promise<void> {\n return new Promise(resolve => {\n const onAnimationFrame = () => {\n if (layerManager.needsUpdate()) {\n layerManager.updateLayers();\n\n deckRenderer.renderLayers({\n pass: 'test',\n views: {},\n effects: [],\n viewports: [layerManager.context.viewport],\n layers: layerManager.getLayers(),\n onViewportActive: layerManager.activateViewport\n });\n resolve();\n return;\n }\n\n setTimeout(onAnimationFrame, 50);\n };\n\n onAnimationFrame();\n });\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {_count as count, Layer} from '@deck.gl/core';\n\nimport type {DefaultProps} from '@deck.gl/core';\nimport type {LayerTestCase, LayerClass} from './lifecycle-test';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop() {}\n\nfunction defaultAssert(condition: any, comment: string): void {\n if (!condition) {\n throw new Error(comment);\n }\n}\n\n// Automatically generate testLayer test cases\nexport function generateLayerTests<LayerT extends Layer>({\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Layer,\n sampleProps = {},\n assert = defaultAssert,\n onBeforeUpdate = noop,\n onAfterUpdate = noop,\n runDefaultAsserts = true\n}: {\n Layer: LayerClass<LayerT>;\n /**\n * Override default props during the test\n */\n sampleProps?: Partial<LayerT['props']>;\n assert?: (condition: any, comment: string) => void;\n onBeforeUpdate?: LayerTestCase<LayerT>['onBeforeUpdate'];\n onAfterUpdate?: LayerTestCase<LayerT>['onAfterUpdate'];\n\n /**\n * Test some typical assumptions after layer updates\n * For primitive layers, assert that layer has model(s).\n * For composite layers, assert that layer has sublayer(s).\n * @default true\n */\n runDefaultAsserts?: boolean;\n}): LayerTestCase<LayerT>[] {\n assert(Layer.layerName, 'Layer should have display name');\n\n function wrapTestCaseTitle(title: string): string {\n return `${Layer.layerName}#${title}`;\n }\n\n const testCases: LayerTestCase<LayerT>[] = [\n {\n title: 'Empty props',\n props: {}\n },\n {\n title: 'Null data',\n // @ts-expect-error null may not be an expected data type\n updateProps: {data: null}\n },\n {\n title: 'Sample data',\n updateProps: sampleProps\n }\n ];\n\n try {\n // Calling constructor for the first time resolves default props\n // eslint-disable-next-line\n new Layer({});\n } catch (error: unknown) {\n assert(false, `Construct ${Layer.layerName} throws: ${(error as Error).message}`);\n }\n\n // @ts-expect-error Access hidden properties\n const {_propTypes: propTypes, _mergedDefaultProps: defaultProps} = Layer;\n\n // Test alternative data formats\n testCases.push(...makeAltDataTestCases<LayerT>(sampleProps, propTypes));\n\n for (const propName in Layer.defaultProps) {\n if (!(propName in sampleProps)) {\n // Do not override user provided props - they may be layer-specific\n const newTestCase =\n makeAltPropTestCase({propName, propTypes, defaultProps, sampleProps, assert}) || [];\n testCases.push(...newTestCase);\n }\n }\n\n testCases.forEach(testCase => {\n testCase.title = wrapTestCaseTitle(testCase.title);\n const beforeFunc = testCase.onBeforeUpdate || noop;\n const afterFunc = testCase.onAfterUpdate || noop;\n testCase.onBeforeUpdate = params => {\n // Generated callback\n beforeFunc(params);\n // User callback\n onBeforeUpdate(params);\n };\n testCase.onAfterUpdate = params => {\n // Generated callback\n afterFunc(params);\n // User callback\n onAfterUpdate(params);\n\n // Default assert\n if (runDefaultAsserts) {\n if (params.layer.isComposite) {\n const {data} = params.layer.props;\n if (data && typeof data === 'object' && count(data)) {\n assert(params.subLayers.length, 'Layer should have sublayers');\n }\n } else {\n assert(params.layer.getModels().length, 'Layer should have models');\n }\n }\n };\n });\n\n return testCases;\n}\n\nfunction makeAltPropTestCase<LayerT extends Layer>({\n propName,\n propTypes,\n defaultProps,\n sampleProps,\n assert\n}: {\n propName: string;\n propTypes: DefaultProps<LayerT['props']>;\n defaultProps: LayerT['props'];\n sampleProps: Partial<LayerT['props']>;\n assert: (condition: any, comment: string) => void;\n}): LayerTestCase<LayerT>[] | null {\n const newProps = {...sampleProps};\n const propDef = propTypes[propName];\n\n if (!propDef) {\n return null;\n }\n\n switch (propDef.type) {\n case 'boolean':\n newProps[propName] = !defaultProps[propName];\n return [\n {\n title: `${propName}: ${String(newProps[propName])}`,\n props: newProps\n }\n ];\n\n case 'number':\n if ('max' in propDef) {\n newProps[propName] = propDef.max;\n } else if ('min' in propDef) {\n newProps[propName] = propDef.min;\n } else {\n newProps[propName] = defaultProps[propName] + 1;\n }\n return [\n {\n title: `${propName}: ${String(newProps[propName])}`,\n props: newProps\n }\n ];\n\n case 'accessor': {\n if (typeof defaultProps[propName] === 'function') {\n return null;\n }\n let callCount = 0;\n newProps[propName] = () => {\n callCount++;\n return defaultProps[propName];\n };\n newProps.updateTriggers = {\n [propName]: 'function'\n };\n const onBeforeUpdate = () => (callCount = 0);\n const onAfterUpdate = () => assert(callCount > 0, 'accessor function is called');\n\n return [\n {\n title: `${propName}: () => ${defaultProps[propName]}`,\n props: newProps,\n onBeforeUpdate,\n onAfterUpdate\n },\n {\n title: `${propName}: updateTrigger`,\n updateProps: {\n updateTriggers: {\n [propName]: 'function+trigger'\n }\n } as Partial<Layer['props']>,\n onBeforeUpdate,\n onAfterUpdate\n }\n ];\n }\n\n default:\n return null;\n }\n}\n\nfunction makeAltDataTestCases<LayerT extends Layer>(\n props: Partial<LayerT['props']>,\n propTypes: DefaultProps<LayerT['props']>\n): LayerTestCase<LayerT>[] {\n const originalData = props.data;\n if (!Array.isArray(originalData)) {\n return [];\n }\n // partial update\n const partialUpdateProps: Partial<Layer['props']> = {\n data: originalData.slice(),\n _dataDiff: () => [{startRow: 0, endRow: 2}]\n };\n // data should support any iterable\n const genIterableProps: Partial<Layer['props']> = {\n data: new Set(originalData),\n _dataDiff: null\n };\n // data in non-iterable form\n const nonIterableProps: Partial<Layer['props']> = {\n data: {\n length: originalData.length\n }\n };\n for (const propName in props) {\n // @ts-ignore propName cannot be used as index\n if (propTypes[propName].type === 'accessor') {\n // @ts-ignore propName cannot be used as index\n nonIterableProps[propName] = (_, info) => props[propName](originalData[info.index], info);\n }\n }\n\n return [\n {\n title: 'Partial update',\n updateProps: partialUpdateProps\n },\n {\n title: 'Generic iterable data',\n updateProps: genIterableProps\n },\n {\n title: 'non-iterable data',\n updateProps: nonIterableProps\n }\n ];\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window, console, setTimeout */\n/* eslint-disable no-console */\nimport {Deck, DeckProps, MapView} from '@deck.gl/core';\nimport type {Device} from '@luma.gl/core';\n\nconst DEFAULT_DECK_PROPS: DeckProps<any> = {\n ...Deck.defaultProps,\n id: 'deckgl-render-test',\n width: 800,\n height: 450,\n style: {position: 'absolute', left: '0px', top: '0px'},\n views: [new MapView({})],\n useDevicePixels: false,\n debug: true\n};\n\nexport type TestCase = {\n name: string;\n /** milliseconds to wait before aborting */\n timeout?: number;\n};\n\ntype TestOptions<TestCaseT extends TestCase, ResultT> = {\n /** Called when a test case starts */\n onTestStart: (testCase: TestCaseT) => void;\n /** Called when a test case passes */\n onTestPass: (testCase: TestCaseT, result: ResultT) => void;\n /** Called when a test case fails */\n onTestFail: (testCase: TestCaseT, result: ResultT | {error: string}) => void;\n\n /** milliseconds to wait for each test case before aborting */\n timeout: number;\n};\n\nconst DEFAULT_TEST_OPTIONS: TestOptions<TestCase, unknown> = {\n // test lifecycle callback\n onTestStart: testCase => console.log(`# ${testCase.name}`),\n onTestPass: testCase => console.log(`ok ${testCase.name} passed`),\n onTestFail: testCase => console.log(`not ok ${testCase.name} failed`),\n\n // milliseconds to wait for each test case before aborting\n timeout: 2000\n};\n\nexport abstract class TestRunner<TestCaseT extends TestCase, ResultT, ExtraOptions = {}> {\n deck: Deck<any> | null = null;\n props: DeckProps<any>;\n isHeadless: boolean;\n isRunning: boolean = false;\n testOptions: TestOptions<TestCaseT, ResultT> & ExtraOptions;\n gpuVendor?: string;\n\n private _testCases: TestCaseT[] = [];\n private _currentTestCase: TestCaseT | null = null;\n private _testCaseData: unknown = null;\n\n /**\n * props\n * Deck props\n */\n constructor(props: DeckProps = {}, options: ExtraOptions) {\n this.props = {...DEFAULT_DECK_PROPS, ...props};\n\n // @ts-ignore browserTestDriver_isHeadless is injected by @probe.gl/test-utils if running in headless browser\n this.isHeadless = Boolean(window.browserTestDriver_isHeadless);\n\n this.testOptions = {...DEFAULT_TEST_OPTIONS, ...options};\n }\n\n get defaultTestCase(): TestCaseT {\n throw new Error('Not implemented');\n }\n\n /**\n * Add testCase(s)\n */\n add(testCases: TestCaseT[]): this {\n if (!Array.isArray(testCases)) {\n testCases = [testCases];\n }\n for (const testCase of testCases) {\n this._testCases.push(testCase);\n }\n return this;\n }\n\n /**\n * Returns a promise that resolves when all the test cases are done\n */\n run(options: Partial<TestOptions<TestCaseT, ResultT> & ExtraOptions> = {}): Promise<void> {\n Object.assign(this.testOptions, options);\n\n return new Promise<void>((resolve, reject) => {\n this.deck = new Deck({\n ...this.props,\n onDeviceInitialized: this._onDeviceInitialized.bind(this),\n onLoad: resolve\n });\n\n this.isRunning = true;\n this._currentTestCase = null;\n })\n .then(() => {\n let promise = Promise.resolve();\n // chain test case promises\n this._testCases.forEach(testCase => {\n promise = promise.then(() => this._runTest(testCase));\n });\n return promise;\n })\n .catch((error: unknown) => {\n this.fail({error: (error as Error).message});\n })\n .finally(() => {\n this.deck!.finalize();\n this.deck = null;\n });\n }\n\n /* Lifecycle methods for subclassing */\n\n initTestCase(testCase: TestCaseT) {\n for (const key in this.defaultTestCase) {\n if (!(key in testCase)) {\n testCase[key] = this.defaultTestCase[key];\n }\n }\n this.testOptions.onTestStart(testCase);\n }\n\n /** Execute the test case. Fails if takes longer than options.timeout */\n abstract runTestCase(testCase: TestCaseT): Promise<void>;\n /** Check the result of the test case. Calls pass() or fail() */\n abstract assert(testCase: TestCaseT): Promise<void>;\n\n /* Utilities */\n\n protected pass(result: ResultT) {\n this.testOptions.onTestPass(this._currentTestCase!, result);\n }\n\n protected fail(result: ResultT | {error: string}) {\n this.testOptions.onTestFail(this._currentTestCase!, result);\n }\n\n /* Private Methods */\n\n private _onDeviceInitialized(device: Device) {\n this.gpuVendor = device.info.vendor;\n }\n\n private async _runTest(testCase: TestCaseT) {\n this._currentTestCase = testCase;\n\n // normalize test case\n this.initTestCase(testCase);\n\n const timeout = testCase.timeout || this.testOptions.timeout;\n const task = this.runTestCase(testCase);\n const timeoutTask = new Promise((_, reject) => {\n setTimeout(() => {\n reject(`Timeout after ${timeout}ms`);\n }, timeout);\n });\n\n try {\n await Promise.race([task, timeoutTask]);\n await this.assert(testCase);\n } catch (err: unknown) {\n if (typeof err === 'string' && err.startsWith('Timeout')) {\n this.fail({error: err});\n }\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window */\n// Get the bounding box of a DOMElement relative to the page\nexport function getBoundingBoxInPage(domElement: HTMLElement): {\n x: number;\n y: number;\n width: number;\n height: number;\n} {\n const bbox = domElement.getBoundingClientRect();\n return {\n x: window.scrollX + bbox.x,\n y: window.scrollY + bbox.y,\n width: bbox.width,\n height: bbox.height\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window */\nimport {TestRunner} from './test-runner';\nimport {getBoundingBoxInPage} from './utils/dom';\n\nimport type {DeckProps, Deck, Layer} from '@deck.gl/core';\n\n// TODO - export from probe.gl\ntype ImageDiffOptions = {\n saveOnFail?: boolean;\n saveAs?: string;\n threshold?: number; // 0.99,\n createDiffImage?: boolean; // false,\n tolerance?: number; // 0.1,\n includeAA?: boolean; // false,\n includeEmpty?: boolean; // true\n platform?: string;\n};\n\ntype DiffImageResult = {\n headless: boolean;\n match: string | number;\n matchPercentage: string;\n success: boolean;\n error: Error | string | null;\n};\n\nexport type SnapshotTestCase = {\n name: string;\n props: DeckProps;\n goldenImage: string;\n onBeforeRender?: (params: {deck: Deck; layers: Layer[]}) => void;\n onAfterRender?: (params: {deck: Deck; layers: Layer[]; done: () => void}) => void;\n timeout?: number;\n imageDiffOptions?: ImageDiffOptions;\n};\n\nconst DEFAULT_TEST_OPTIONS = {\n imageDiffOptions: {}\n};\n\nconst DEFAULT_TEST_CASE: SnapshotTestCase = {\n name: 'Unnamed snapshot test',\n props: {},\n onBeforeRender: ({deck, layers}) => {\n // eslint-disable-line\n },\n onAfterRender: ({deck, layers, done}) => {\n if (\n // @ts-expect-error accessing private\n !deck.layerManager?.needsUpdate() &&\n layers.every(layer => layer.isLoaded)\n ) {\n done(); // eslint-disable-line\n }\n },\n goldenImage: ''\n};\n\nexport class SnapshotTestRunner extends TestRunner<\n SnapshotTestCase,\n DiffImageResult,\n {imageDiffOptions: ImageDiffOptions}\n> {\n private _isDiffing: boolean = false;\n\n constructor(props) {\n super(props, DEFAULT_TEST_OPTIONS);\n\n this._isDiffing = false;\n }\n\n get defaultTestCase() {\n return DEFAULT_TEST_CASE;\n }\n\n initTestCase(testCase: SnapshotTestCase) {\n super.initTestCase(testCase);\n if (!testCase.goldenImage) {\n throw new Error(`Test case ${testCase.name} does not have golden image`);\n }\n }\n\n runTestCase(testCase: SnapshotTestCase) {\n const deck = this.deck!;\n\n return new Promise<void>(resolve => {\n deck.setProps({\n ...this.props,\n ...testCase,\n onBeforeRender: () => {\n testCase.onBeforeRender!({\n deck,\n // @ts-expect-error Accessing protected layerManager\n layers: this.deck.layerManager.getLayers()\n });\n },\n onAfterRender: () => {\n testCase.onAfterRender!({\n deck,\n // @ts-expect-error Accessing protected layerManager\n layers: this.deck.layerManager.getLayers(),\n done: resolve\n });\n }\n });\n });\n }\n\n async assert(testCase: SnapshotTestCase) {\n if (this._isDiffing) {\n // already performing diffing\n return;\n }\n this._isDiffing = true;\n\n const diffOptions = {\n ...this.testOptions.imageDiffOptions,\n ...testCase.imageDiffOptions,\n goldenImage: testCase.goldenImage,\n region: getBoundingBoxInPage(this.deck!.getCanvas()!)\n };\n // Take screenshot and compare\n const result = await window.browserTestDriver_captureAndDiffScreen(diffOptions);\n\n // If failed, try if we have a platform specific golden image\n let resultOverride;\n const platform = this.testOptions.imageDiffOptions?.platform?.toLowerCase();\n if (!result.success) {\n diffOptions.goldenImage = diffOptions.goldenImage.replace(\n 'golden-images/',\n `golden-images/platform-overrides/${platform}/`\n );\n resultOverride = await window.browserTestDriver_captureAndDiffScreen(diffOptions);\n }\n\n // invoke user callback\n if (result.success || resultOverride.success) {\n this.pass(result);\n } else {\n this.fail(result);\n }\n\n this._isDiffing = false;\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global window */\nimport {TestRunner} from './test-runner';\nimport type {Deck, Layer} from '@deck.gl/core';\n\ntype InteractionEvent =\n | {\n type: string;\n [key: string]: any;\n }\n | {\n wait: number;\n };\n\nexport type InteractionTestCase = {\n name: string;\n events: InteractionEvent[];\n timeout?: number;\n context?: any;\n onBeforeEvents: (params: {deck: Deck}) => any;\n onAfterEvents: (params: {deck: Deck; layers: Layer[]; context: any}) => void;\n};\n\nconst DEFAULT_TEST_CASE: InteractionTestCase = {\n name: 'Unnamed interaction test',\n events: [],\n onBeforeEvents: ({deck}) => {},\n onAfterEvents: ({deck, layers, context}) => {}\n};\n\nfunction sleep(timeout: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, timeout));\n}\n\nexport class InteractionTestRunner extends TestRunner<InteractionTestCase, {}> {\n get defaultTestCase() {\n return DEFAULT_TEST_CASE;\n }\n\n // chain events\n async runTestCase(testCase: InteractionTestCase) {\n testCase.context = testCase.onBeforeEvents({\n deck: this.deck!\n });\n\n for (const event of testCase.events) {\n if (event.wait) {\n await sleep(event.wait);\n } else {\n await window.browserTestDriver_emulateInput(event);\n }\n }\n }\n\n async assert(testCase) {\n testCase.onAfterEvents({\n deck: this.deck,\n // @ts-expect-error Accessing protected layerManager\n layers: this.deck.layerManager.getLayers(),\n context: testCase.context\n });\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;mBAAAA;EAAA,sBAAAC;EAAA;;;;;ACUM,SAAU,iBAAiB,OAAc,WAAkB;AAC/D,QAAM,WAAW,CAAA;AACjB,QAAM,eAAe,MAAM,UAAS,EAAG,CAAC,EAAE;AAC1C,QAAM,gBAAgB,YAClB,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC,IAC1C,aAAa,cAAc,OAAM;AACrC,aAAW,SAAS,eAAe;AACjC,WAAO,OAAO,UAAU,MAAO,QAAQ;EACzC;AAEA,SAAO;AACT;;;ACNM,SAAU,eACd,OACA,YAAoB,IAAE;AAGtB,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,MAAM,YAAY,SAAS,CAAC;EAC5C;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,UAAQ,eAAe,MAAM,SAAS,CAAC;EAC1D;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,eAAW,OAAO,OAAO;AACvB,YAAM,GAAG,IAAI,eAAe,MAAM,GAAG,GAAG,SAAS;IACnD;EACF;AACA,SAAO;AACT;;;AC5BA,wBAAsC;AAG/B,IAAM,SAAS,iCAAe,IAAI,6BAAW,CAAA,CAAE;AAPtD;AAQO,IAAM,OAAK,0DAAa,OAAM;AAErC,WAAW,YAAY,WAAW,aAAa;;;ACH/C,IAAAC,qBAAsB;;;ACHtB,kBAAkD;AAQlD,IAAM,eAAe,IAAI,oBAAQ,CAAA,CAAE,EAAE,aAAa;EAChD,OAAO;EACP,QAAQ;EACR,WAAW,EAAC,WAAW,GAAG,UAAU,GAAG,MAAM,EAAC;CAC/C;AAED,SAAS,eAAe,OAAgB,OAAa;AACnD,MAAI,OAAO;AACT,UAAM;EACR;AACF;AAaA,SAAS,uBAAuB,EAC9B,OACA,WAAW,cACX,UAAU,eAAc,GACG;AAC3B,QAAM,eAAe,IAAI,yBAAa,QAAQ,EAAC,SAAQ,CAAC;AACxD,eAAa,SAAS;IACpB,SAAS,WAAS,QAAQ,OAAO,gBAAgB,MAAM,IAAI;GAC5D;AAED,eAAa,UAAU,CAAC,KAAK,CAAC;AAC9B,SAAO;AACT;AAqBM,SAAU,oBACd,MAGC;AAKD,QAAM,eAAe,uBAAuB,IAAI;AAChD,MAAI,KAAK,aAAa,OAAO;AAC3B,WAAO;MACL,UAAU,MAAM,aAAa,SAAQ;;EAEzC;AACA,eAAa,SAAQ;AACrB,SAAO;AACT;AAqBA,eAAsB,yBACpB,MAGC;AAKD,QAAM,eAAe,uBAAuB,IAAI;AAChD,QAAM,eAAe,IAAI,yBAAa,MAAM;AAC5C,SAAO,CAAC,KAAK,MAAM,UAAU;AAC3B,UAAM,OAAO,EAAC,cAAc,cAAc,mBAAmB,CAAA,EAAE,CAAC;EAClE;AACA,MAAI,KAAK,aAAa,OAAO;AAC3B,WAAO;MACL,UAAU,MAAM,aAAa,SAAQ;;EAEzC;AACA,eAAa,SAAQ;AACrB,SAAO;AACT;AAsFM,SAAU,UAAgC,MAA8B;AAC5E,QAAM,EAAC,OAAO,YAAY,CAAA,GAAI,QAAQ,CAAA,GAAI,UAAU,gBAAgB,WAAW,SAAQ,IAAI;AAE3F,QAAM,YAAY,gBAAgB,WAAW,MAAM,aAAa,IAAI;AAEpE,MAAI,QAAQ,IAAI,MAAK;AAErB,aAAW,YAAY,WAAW;AAEhC,UAAM,WAAW,EAAC,GAAG,MAAM,MAAK;AAEhC,UAAM,EAAC,OAAO,UAAU,OAAM,IAAI,mBAChC,UACA,WACA,OACA,OACA,SAAS;AAGX,gCAA4B,UAAU,UAAU,UAAU,MAAM;AAGhE,WAAO,KAAK,MAAM,EAAE,QAAQ,OAAK,SAAS,OAAO,CAAC,CAAC,CAAC;AACpD,YAAQ;EACV;AAEA,QAAM,QAAQ,uBAAuB,SAAS;AAC9C,MAAI,OAAO;AACT,YAAQ,OAAO,GAAG,MAAM,uCAAuC;EACjE;AACF;AAMA,eAAsB,eACpB,MAA8B;AAE9B,QAAM,EAAC,OAAO,YAAY,CAAA,GAAI,QAAQ,CAAA,GAAI,UAAU,gBAAgB,WAAW,SAAQ,IAAI;AAE3F,QAAM,YAAY,gBAAgB,WAAW,MAAM,aAAa,IAAI;AAEpE,MAAI,QAAQ,IAAI,MAAK;AAErB,aAAW,YAAY,WAAW;AAEhC,UAAM,WAAW,EAAC,GAAG,MAAM,MAAK;AAEhC,UAAM,EAAC,OAAO,UAAU,OAAM,IAAI,mBAChC,UACA,WACA,OACA,OACA,SAAS;AAGX,gCAA4B,UAAU,UAAU,UAAU,MAAM;AAEhE,WAAO,CAAC,SAAS,UAAU;AACzB,YAAM,OAAO,SAAS;AACtB,kCAA4B,UAAU,UAAU,UAAU,MAAM;IAClE;AAGA,WAAO,KAAK,MAAM,EAAE,QAAQ,OAAK,SAAS,OAAO,CAAC,CAAC,CAAC;AACpD,YAAQ;EACV;AAGA,QAAM,QAAQ,MAAM,4BAA4B,SAAS;AACzD,MAAI,OAAO;AACT,YAAQ,OAAO,GAAG,MAAM,uCAAuC;EACjE;AACF;AAEA,SAAS,gBACP,WACA,EACE,WAAW,cACX,UACA,UAAU,eAAc,GAKzB;AAED,QAAM,oBAAoB,kBAAiB;AAE3C,QAAM,eAAe,IAAI,yBAAa,QAAQ,EAAC,UAAU,SAAQ,CAAC;AAClE,QAAM,eAAe,IAAI,yBAAa,MAAM;AAE5C,QAAM,QAAQ;IACZ,aAAa;IACb,mBAAmB;IACnB,SAAS,WAAS,QAAQ,OAAO,SAAS;;AAE5C,eAAa,SAAS,KAAK;AAC3B,eAAa,SAAS,KAAK;AAE3B,SAAO,EAAC,cAAc,cAAc,kBAAiB;AACvD;AAEA,SAAS,uBAAuB,EAC9B,cACA,cACA,kBAAiB,GACH;AACd,eAAa,UAAU,CAAA,CAAE;AACzB,eAAa,SAAQ;AACrB,eAAa,SAAQ;AAErB,SAAO,sBAAsB,iBAAiB;AAChD;AAOA,eAAe,4BAA4B,EACzC,cACA,cACA,kBAAiB,GACH;AACd,eAAa,UAAU,CAAA,CAAE;AAMzB,QAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,CAAC,CAAC;AAEnD,eAAa,SAAQ;AACrB,eAAa,SAAQ;AAErB,SAAO,sBAAsB,iBAAiB;AAChD;AAEA,SAAS,oBAAiB;AAExB,QAAM,gBAAiB,KAAK,MAAuB,IAAI,iBAAiB;AACxE,SAAO;IACL,WAAW,cAAc,IAAI,mBAAmB,EAAE;IAClD,QAAQ,cAAc,IAAI,gBAAgB,EAAE;;AAEhD;AAEA,SAAS,sBAAsB,mBAAyC;AACtE,QAAM,iBAAiB,kBAAiB;AAExC,aAAW,gBAAgB,gBAAgB;AACzC,QAAI,eAAe,YAAY,MAAM,kBAAkB,YAAY,GAAG;AACpE,aAAO,IAAI,MACT,GAAG,eAAe,YAAY,IAAI,kBAAkB,YAAY,KAAK,eAAe;IAExF;EACF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAc,OAAiB,YAAsB;AACxE,QAAM,SAA8B,CAAA;AACpC,MAAI,OAAO;AACT,eAAW,gBAAgB,OAAO;AAChC,aAAO,YAAY,IAAI,WAAW,OAAO,eAAe,KAAK,GAAG,YAAY;IAC9E;EACF;AACA,SAAO;AACT;AAEA,SAAS,4BACP,UACA,UACA,UACA,QAA2B;AAG3B,MAAI,SAAS,eAAe;AAG1B,UAAM,YAAY,SAAS,cACtB,SAAqC,aAAY,IAClD,CAAA;AACJ,UAAM,WAAW,UAAU,SAAS,UAAU,CAAC,IAAI;AAEnD,aAAS,cAAc;MACrB;MACA,OAAO;MACP;MACA;MACA;MACA,OAAO;KACR;EACH;AACF;AAEA,SAAS,mBACP,UACA,EAAC,cAAc,aAAY,GAC3B,OACA,OACA,YAAsB;AAKtB,QAAM,EAAC,OAAO,aAAa,gBAAgB,WAAW,aAAa,QAAQ,SAAQ,IAAI;AAEvF,MAAI,gBAAgB;AAClB,mBAAe,EAAC,OAAO,SAAQ,CAAC;EAClC;AAEA,MAAI,OAAO;AAET,YAAQ,IAAK,MAAM,YAAmC,KAAK;EAC7D,WAAW,aAAa;AAEtB,YAAQ,MAAM,MAAM,WAAW;EACjC;AAGA,UAAQ,SAAS,SAAS;AAC1B,QAAM,SAAS,YAAY,OAAO,OAAO,UAAU;AACnD,QAAM,aAAa,MAAK;AACtB,iBAAa,aAAa;MACxB,MAAM;MACN,OAAO,CAAA;MACP,SAAS,CAAA;MACT,WAAW,CAAC,QAAQ;MACpB,QAAQ,aAAa,UAAS;MAC9B,kBAAkB,aAAa;KAChC;EACH;AAEA,eAAa,UAAU,CAAC,KAAK,CAAC;AAC9B,aAAU;AAGV,MAAI,aAAa,YAAW,GAAI;AAC9B,iBAAa,aAAY;AACzB,eAAU;EACZ;AAEA,SAAO,EAAC,OAAO,OAAM;AACvB;AAGA,SAAS,OAAO,EAAC,cAAc,aAAY,GAAgB;AACzD,SAAO,IAAI,QAAQ,aAAU;AAC3B,UAAM,mBAAmB,MAAK;AAC5B,UAAI,aAAa,YAAW,GAAI;AAC9B,qBAAa,aAAY;AAEzB,qBAAa,aAAa;UACxB,MAAM;UACN,OAAO,CAAA;UACP,SAAS,CAAA;UACT,WAAW,CAAC,aAAa,QAAQ,QAAQ;UACzC,QAAQ,aAAa,UAAS;UAC9B,kBAAkB,aAAa;SAChC;AACD,gBAAO;AACP;MACF;AAEA,iBAAW,kBAAkB,EAAE;IACjC;AAEA,qBAAgB;EAClB,CAAC;AACH;;;AD3cA,IAAI,sBAAsB;AAC1B,IAAI,qBAAqB;AAEzB,SAAS,uBAAoB;AAC3B,MAAI,CAAC,qBAAqB;AACxB,0BAAsB;AAEtB,YAAQ,KACN,mMAEuC;EAE3C;AACA,SAAO;AACT;AAGA,SAAS,qBAAkB;AACzB,MAAI,CAAC,oBAAoB;AACvB,yBAAqB;AAErB,YAAQ,KACN,gLAEmD;EAEvD;AACA,SAAO,SAAQ,IAAmC,MAAK;AACzD;AAMM,SAAUC,WACd,MAGC;AAED,QAAM,YAAY,KAAK,aAAa,qBAAoB;AACxD,QAAM,WAAW,KAAK,YAAY,mBAAkB;AACpD,YAAc,EAAC,GAAG,MAAM,WAAW,SAAQ,CAAC;AAC9C;AAMA,eAAsBC,gBACpB,MAGC;AAED,QAAM,YAAY,KAAK,aAAa,qBAAoB;AACxD,QAAM,WAAW,KAAK,YAAY,mBAAkB;AACpD,QAAM,eAAmB,EAAC,GAAG,MAAM,WAAW,SAAQ,CAAC;AACzD;;;AEhFA,IAAAC,eAAqC;AAMrC,SAAS,OAAI;AAAI;AAEjB,SAAS,cAAc,WAAgB,SAAe;AACpD,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,OAAO;EACzB;AACF;AAGM,SAAU,mBAAyC;;EAEvD;EACA,cAAc,CAAA;EACd,SAAS;EACT,iBAAiB;EACjB,gBAAgB;EAChB,oBAAoB;AAAI,GAkBzB;AACC,SAAO,MAAM,WAAW,gCAAgC;AAExD,WAAS,kBAAkB,OAAa;AACtC,WAAO,GAAG,MAAM,aAAa;EAC/B;AAEA,QAAM,YAAqC;IACzC;MACE,OAAO;MACP,OAAO,CAAA;;IAET;MACE,OAAO;;MAEP,aAAa,EAAC,MAAM,KAAI;;IAE1B;MACE,OAAO;MACP,aAAa;;;AAIjB,MAAI;AAGF,QAAI,MAAM,CAAA,CAAE;EACd,SAAS,OAAP;AACA,WAAO,OAAO,aAAa,MAAM,qBAAsB,MAAgB,SAAS;EAClF;AAGA,QAAM,EAAC,YAAY,WAAW,qBAAqB,aAAY,IAAI;AAGnE,YAAU,KAAK,GAAG,qBAA6B,aAAa,SAAS,CAAC;AAEtE,aAAW,YAAY,MAAM,cAAc;AACzC,QAAI,EAAE,YAAY,cAAc;AAE9B,YAAM,cACJ,oBAAoB,EAAC,UAAU,WAAW,cAAc,aAAa,OAAM,CAAC,KAAK,CAAA;AACnF,gBAAU,KAAK,GAAG,WAAW;IAC/B;EACF;AAEA,YAAU,QAAQ,cAAW;AAC3B,aAAS,QAAQ,kBAAkB,SAAS,KAAK;AACjD,UAAM,aAAa,SAAS,kBAAkB;AAC9C,UAAM,YAAY,SAAS,iBAAiB;AAC5C,aAAS,iBAAiB,YAAS;AAEjC,iBAAW,MAAM;AAEjB,qBAAe,MAAM;IACvB;AACA,aAAS,gBAAgB,YAAS;AAEhC,gBAAU,MAAM;AAEhB,oBAAc,MAAM;AAGpB,UAAI,mBAAmB;AACrB,YAAI,OAAO,MAAM,aAAa;AAC5B,gBAAM,EAAC,KAAI,IAAI,OAAO,MAAM;AAC5B,cAAI,QAAQ,OAAO,SAAS,gBAAY,aAAAC,QAAM,IAAI,GAAG;AACnD,mBAAO,OAAO,UAAU,QAAQ,6BAA6B;UAC/D;QACF,OAAO;AACL,iBAAO,OAAO,MAAM,UAAS,EAAG,QAAQ,0BAA0B;QACpE;MACF;IACF;EACF,CAAC;AAED,SAAO;AACT;AAEA,SAAS,oBAA0C,EACjD,UACA,WACA,cACA,aACA,OAAM,GAOP;AACC,QAAM,WAAW,EAAC,GAAG,YAAW;AAChC,QAAM,UAAU,UAAU,QAAQ;AAElC,MAAI,CAAC,SAAS;AACZ,WAAO;EACT;AAEA,UAAQ,QAAQ,MAAM;IACpB,KAAK;AACH,eAAS,QAAQ,IAAI,CAAC,aAAa,QAAQ;AAC3C,aAAO;QACL;UACE,OAAO,GAAG,aAAa,OAAO,SAAS,QAAQ,CAAC;UAChD,OAAO;;;IAIb,KAAK;AACH,UAAI,SAAS,SAAS;AACpB,iBAAS,QAAQ,IAAI,QAAQ;MAC/B,WAAW,SAAS,SAAS;AAC3B,iBAAS,QAAQ,IAAI,QAAQ;MAC/B,OAAO;AACL,iBAAS,QAAQ,IAAI,aAAa,QAAQ,IAAI;MAChD;AACA,aAAO;QACL;UACE,OAAO,GAAG,aAAa,OAAO,SAAS,QAAQ,CAAC;UAChD,OAAO;;;IAIb,KAAK,YAAY;AACf,UAAI,OAAO,aAAa,QAAQ,MAAM,YAAY;AAChD,eAAO;MACT;AACA,UAAI,YAAY;AAChB,eAAS,QAAQ,IAAI,MAAK;AACxB;AACA,eAAO,aAAa,QAAQ;MAC9B;AACA,eAAS,iBAAiB;QACxB,CAAC,QAAQ,GAAG;;AAEd,YAAM,iBAAiB,MAAO,YAAY;AAC1C,YAAM,gBAAgB,MAAM,OAAO,YAAY,GAAG,6BAA6B;AAE/E,aAAO;QACL;UACE,OAAO,GAAG,mBAAmB,aAAa,QAAQ;UAClD,OAAO;UACP;UACA;;QAEF;UACE,OAAO,GAAG;UACV,aAAa;YACX,gBAAgB;cACd,CAAC,QAAQ,GAAG;;;UAGhB;UACA;;;IAGN;IAEA;AACE,aAAO;EACX;AACF;AAEA,SAAS,qBACP,OACA,WAAwC;AAExC,QAAM,eAAe,MAAM;AAC3B,MAAI,CAAC,MAAM,QAAQ,YAAY,GAAG;AAChC,WAAO,CAAA;EACT;AAEA,QAAM,qBAA8C;IAClD,MAAM,aAAa,MAAK;IACxB,WAAW,MAAM,CAAC,EAAC,UAAU,GAAG,QAAQ,EAAC,CAAC;;AAG5C,QAAM,mBAA4C;IAChD,MAAM,IAAI,IAAI,YAAY;IAC1B,WAAW;;AAGb,QAAM,mBAA4C;IAChD,MAAM;MACJ,QAAQ,aAAa;;;AAGzB,aAAW,YAAY,OAAO;AAE5B,QAAI,UAAU,QAAQ,EAAE,SAAS,YAAY;AAE3C,uBAAiB,QAAQ,IAAI,CAAC,GAAG,SAAS,MAAM,QAAQ,EAAE,aAAa,KAAK,KAAK,GAAG,IAAI;IAC1F;EACF;AAEA,SAAO;IACL;MACE,OAAO;MACP,aAAa;;IAEf;MACE,OAAO;MACP,aAAa;;IAEf;MACE,OAAO;MACP,aAAa;;;AAGnB;;;ACxPA,IAAAC,eAAuC;AAGvC,IAAM,qBAAqC;EACzC,GAAG,kBAAK;EACR,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,OAAO,EAAC,UAAU,YAAY,MAAM,OAAO,KAAK,MAAK;EACrD,OAAO,CAAC,IAAI,qBAAQ,CAAA,CAAE,CAAC;EACvB,iBAAiB;EACjB,OAAO;;AAqBT,IAAM,uBAAuD;;EAE3D,aAAa,cAAY,QAAQ,IAAI,KAAK,SAAS,MAAM;EACzD,YAAY,cAAY,QAAQ,IAAI,MAAM,SAAS,aAAa;EAChE,YAAY,cAAY,QAAQ,IAAI,UAAU,SAAS,aAAa;;EAGpE,SAAS;;AAGL,IAAgB,aAAhB,MAA0B;;;;;EAgB9B,YAAY,QAAmB,CAAA,GAAI,SAAqB;AAfxD,SAAA,OAAyB;AAGzB,SAAA,YAAqB;AAIb,SAAA,aAA0B,CAAA;AAC1B,SAAA,mBAAqC;AACrC,SAAA,gBAAyB;AAO/B,SAAK,QAAQ,EAAC,GAAG,oBAAoB,GAAG,MAAK;AAG7C,SAAK,aAAa,QAAQ,OAAO,4BAA4B;AAE7D,SAAK,cAAc,EAAC,GAAG,sBAAsB,GAAG,QAAO;EACzD;EAEA,IAAI,kBAAe;AACjB,UAAM,IAAI,MAAM,iBAAiB;EACnC;;;;EAKA,IAAI,WAAsB;AACxB,QAAI,CAAC,MAAM,QAAQ,SAAS,GAAG;AAC7B,kBAAY,CAAC,SAAS;IACxB;AACA,eAAW,YAAY,WAAW;AAChC,WAAK,WAAW,KAAK,QAAQ;IAC/B;AACA,WAAO;EACT;;;;EAKA,IAAI,UAAmE,CAAA,GAAE;AACvE,WAAO,OAAO,KAAK,aAAa,OAAO;AAEvC,WAAO,IAAI,QAAc,CAAC,SAAS,WAAU;AAC3C,WAAK,OAAO,IAAI,kBAAK;QACnB,GAAG,KAAK;QACR,qBAAqB,KAAK,qBAAqB,KAAK,IAAI;QACxD,QAAQ;OACT;AAED,WAAK,YAAY;AACjB,WAAK,mBAAmB;IAC1B,CAAC,EACE,KAAK,MAAK;AACT,UAAI,UAAU,QAAQ,QAAO;AAE7B,WAAK,WAAW,QAAQ,cAAW;AACjC,kBAAU,QAAQ,KAAK,MAAM,KAAK,SAAS,QAAQ,CAAC;MACtD,CAAC;AACD,aAAO;IACT,CAAC,EACA,MAAM,CAAC,UAAkB;AACxB,WAAK,KAAK,EAAC,OAAQ,MAAgB,QAAO,CAAC;IAC7C,CAAC,EACA,QAAQ,MAAK;AACZ,WAAK,KAAM,SAAQ;AACnB,WAAK,OAAO;IACd,CAAC;EACL;;EAIA,aAAa,UAAmB;AAC9B,eAAW,OAAO,KAAK,iBAAiB;AACtC,UAAI,EAAE,OAAO,WAAW;AACtB,iBAAS,GAAG,IAAI,KAAK,gBAAgB,GAAG;MAC1C;IACF;AACA,SAAK,YAAY,YAAY,QAAQ;EACvC;;EASU,KAAK,QAAe;AAC5B,SAAK,YAAY,WAAW,KAAK,kBAAmB,MAAM;EAC5D;EAEU,KAAK,QAAiC;AAC9C,SAAK,YAAY,WAAW,KAAK,kBAAmB,MAAM;EAC5D;;EAIQ,qBAAqBC,SAAc;AACzC,SAAK,YAAYA,QAAO,KAAK;EAC/B;EAEQ,MAAM,SAAS,UAAmB;AACxC,SAAK,mBAAmB;AAGxB,SAAK,aAAa,QAAQ;AAE1B,UAAM,UAAU,SAAS,WAAW,KAAK,YAAY;AACrD,UAAM,OAAO,KAAK,YAAY,QAAQ;AACtC,UAAM,cAAc,IAAI,QAAQ,CAAC,GAAG,WAAU;AAC5C,iBAAW,MAAK;AACd,eAAO,iBAAiB,WAAW;MACrC,GAAG,OAAO;IACZ,CAAC;AAED,QAAI;AACF,YAAM,QAAQ,KAAK,CAAC,MAAM,WAAW,CAAC;AACtC,YAAM,KAAK,OAAO,QAAQ;IAC5B,SAAS,KAAP;AACA,UAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,SAAS,GAAG;AACxD,aAAK,KAAK,EAAC,OAAO,IAAG,CAAC;MACxB;IACF;EACF;;;;AC3KI,SAAU,qBAAqB,YAAuB;AAM1D,QAAM,OAAO,WAAW,sBAAqB;AAC7C,SAAO;IACL,GAAG,OAAO,UAAU,KAAK;IACzB,GAAG,OAAO,UAAU,KAAK;IACzB,OAAO,KAAK;IACZ,QAAQ,KAAK;;AAEjB;;;ACqBA,IAAMC,wBAAuB;EAC3B,kBAAkB,CAAA;;AAGpB,IAAM,oBAAsC;EAC1C,MAAM;EACN,OAAO,CAAA;EACP,gBAAgB,CAAC,EAAC,MAAM,OAAM,MAAK;EAEnC;EACA,eAAe,CAAC,EAAC,MAAM,QAAQ,KAAI,MAAK;AAlD1C,QAAAC;AAmDI;;MAEE,GAACA,MAAA,KAAK,iBAAL,gBAAAA,IAAmB,kBACpB,OAAO,MAAM,WAAS,MAAM,QAAQ;MACpC;AACA,WAAI;IACN;EACF;EACA,aAAa;;AAGT,IAAO,qBAAP,cAAkC,WAIvC;EAGC,YAAY,OAAK;AACf,UAAM,OAAOD,qBAAoB;AAH3B,SAAA,aAAsB;AAK5B,SAAK,aAAa;EACpB;EAEA,IAAI,kBAAe;AACjB,WAAO;EACT;EAEA,aAAa,UAA0B;AACrC,UAAM,aAAa,QAAQ;AAC3B,QAAI,CAAC,SAAS,aAAa;AACzB,YAAM,IAAI,MAAM,aAAa,SAAS,iCAAiC;IACzE;EACF;EAEA,YAAY,UAA0B;AACpC,UAAM,OAAO,KAAK;AAElB,WAAO,IAAI,QAAc,aAAU;AACjC,WAAK,SAAS;QACZ,GAAG,KAAK;QACR,GAAG;QACH,gBAAgB,MAAK;AACnB,mBAAS,eAAgB;YACvB;;YAEA,QAAQ,KAAK,KAAK,aAAa,UAAS;WACzC;QACH;QACA,eAAe,MAAK;AAClB,mBAAS,cAAe;YACtB;;YAEA,QAAQ,KAAK,KAAK,aAAa,UAAS;YACxC,MAAM;WACP;QACH;OACD;IACH,CAAC;EACH;EAEA,MAAM,OAAO,UAA0B;AAhHzC,QAAAC,KAAA;AAiHI,QAAI,KAAK,YAAY;AAEnB;IACF;AACA,SAAK,aAAa;AAElB,UAAM,cAAc;MAClB,GAAG,KAAK,YAAY;MACpB,GAAG,SAAS;MACZ,aAAa,SAAS;MACtB,QAAQ,qBAAqB,KAAK,KAAM,UAAS,CAAG;;AAGtD,UAAM,SAAS,MAAM,OAAO,uCAAuC,WAAW;AAG9E,QAAI;AACJ,UAAM,YAAW,MAAAA,MAAA,KAAK,YAAY,qBAAjB,gBAAAA,IAAmC,aAAnC,mBAA6C;AAC9D,QAAI,CAAC,OAAO,SAAS;AACnB,kBAAY,cAAc,YAAY,YAAY,QAChD,kBACA,oCAAoC,WAAW;AAEjD,uBAAiB,MAAM,OAAO,uCAAuC,WAAW;IAClF;AAGA,QAAI,OAAO,WAAW,eAAe,SAAS;AAC5C,WAAK,KAAK,MAAM;IAClB,OAAO;AACL,WAAK,KAAK,MAAM;IAClB;AAEA,SAAK,aAAa;EACpB;;;;ACzHF,IAAMC,qBAAyC;EAC7C,MAAM;EACN,QAAQ,CAAA;EACR,gBAAgB,CAAC,EAAC,KAAI,MAAK;EAAE;EAC7B,eAAe,CAAC,EAAC,MAAM,QAAQ,QAAO,MAAK;EAAE;;AAG/C,SAAS,MAAM,SAAe;AAC5B,SAAO,IAAI,QAAQ,aAAW,OAAO,WAAW,SAAS,OAAO,CAAC;AACnE;AAEM,IAAO,wBAAP,cAAqC,WAAmC;EAC5E,IAAI,kBAAe;AACjB,WAAOA;EACT;;EAGA,MAAM,YAAY,UAA6B;AAC7C,aAAS,UAAU,SAAS,eAAe;MACzC,MAAM,KAAK;KACZ;AAED,eAAW,SAAS,SAAS,QAAQ;AACnC,UAAI,MAAM,MAAM;AACd,cAAM,MAAM,MAAM,IAAI;MACxB,OAAO;AACL,cAAM,OAAO,+BAA+B,KAAK;MACnD;IACF;EACF;EAEA,MAAM,OAAO,UAAQ;AACnB,aAAS,cAAc;MACrB,MAAM,KAAK;;MAEX,QAAQ,KAAK,KAAK,aAAa,UAAS;MACxC,SAAS,SAAS;KACnB;EACH;;",
|
|
6
|
+
"names": ["testLayer", "testLayerAsync", "import_test_utils", "testLayer", "testLayerAsync", "import_core", "count", "import_core", "device", "DEFAULT_TEST_OPTIONS", "_a", "DEFAULT_TEST_CASE"]
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export { getLayerUniforms } from "./utils/layer.js";
|
|
2
2
|
export { toLowPrecision } from "./utils/precision.js";
|
|
3
3
|
export { gl, device } from "./utils/setup-gl.js";
|
|
4
|
-
export { testLayer, testLayerAsync, testInitializeLayer, testInitializeLayerAsync } from "./
|
|
4
|
+
export { testLayer, testLayerAsync, testInitializeLayer, testInitializeLayerAsync } from "./tape.js";
|
|
5
5
|
export { generateLayerTests } from "./generate-layer-tests.js";
|
|
6
6
|
export { TestRunner } from "./test-runner.js";
|
|
7
7
|
export { SnapshotTestRunner } from "./snapshot-test-runner.js";
|
|
8
8
|
export { InteractionTestRunner } from "./interaction-test-runner.js";
|
|
9
|
-
export type { LayerTestCase } from "./
|
|
9
|
+
export type { LayerTestCase, ResetSpy, SpyFactory } from "./tape.js";
|
|
10
10
|
export type { SnapshotTestCase } from "./snapshot-test-runner.js";
|
|
11
11
|
export type { InteractionTestCase } from "./interaction-test-runner.js";
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,gBAAgB,EAAC,yBAAsB;AAC/C,OAAO,EAAC,cAAc,EAAC,6BAA0B;AACjD,OAAO,EAAC,EAAE,EAAE,MAAM,EAAC,4BAAyB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,gBAAgB,EAAC,yBAAsB;AAC/C,OAAO,EAAC,cAAc,EAAC,6BAA0B;AACjD,OAAO,EAAC,EAAE,EAAE,MAAM,EAAC,4BAAyB;AAI5C,OAAO,EAAC,SAAS,EAAE,cAAc,EAAE,mBAAmB,EAAE,wBAAwB,EAAC,kBAAe;AAChG,OAAO,EAAC,kBAAkB,EAAC,kCAA+B;AAG1D,OAAO,EAAC,UAAU,EAAC,yBAAsB;AAGzC,OAAO,EAAC,kBAAkB,EAAC,kCAA+B;AAE1D,OAAO,EAAC,qBAAqB,EAAC,qCAAkC;AAEhE,YAAY,EAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAC,kBAAe;AAChE,YAAY,EAAC,gBAAgB,EAAC,kCAA+B;AAC7D,YAAY,EAAC,mBAAmB,EAAC,qCAAkC"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,8 @@ export { getLayerUniforms } from "./utils/layer.js";
|
|
|
5
5
|
export { toLowPrecision } from "./utils/precision.js";
|
|
6
6
|
export { gl, device } from "./utils/setup-gl.js";
|
|
7
7
|
// Utilities for update tests (lifecycle tests)
|
|
8
|
-
export
|
|
8
|
+
// Re-export from tape.ts which provides default spy factory for backward compat
|
|
9
|
+
export { testLayer, testLayerAsync, testInitializeLayer, testInitializeLayerAsync } from "./tape.js";
|
|
9
10
|
export { generateLayerTests } from "./generate-layer-tests.js";
|
|
10
11
|
// Basic utility for rendering multiple scenes (could go into "deck.gl/core")
|
|
11
12
|
export { TestRunner } from "./test-runner.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EAAC,gBAAgB,EAAC,yBAAsB;AAC/C,OAAO,EAAC,cAAc,EAAC,6BAA0B;AACjD,OAAO,EAAC,EAAE,EAAE,MAAM,EAAC,4BAAyB;AAE5C,+CAA+C;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EAAC,gBAAgB,EAAC,yBAAsB;AAC/C,OAAO,EAAC,cAAc,EAAC,6BAA0B;AACjD,OAAO,EAAC,EAAE,EAAE,MAAM,EAAC,4BAAyB;AAE5C,+CAA+C;AAC/C,gFAAgF;AAChF,OAAO,EAAC,SAAS,EAAE,cAAc,EAAE,mBAAmB,EAAE,wBAAwB,EAAC,kBAAe;AAChG,OAAO,EAAC,kBAAkB,EAAC,kCAA+B;AAE1D,6EAA6E;AAC7E,OAAO,EAAC,UAAU,EAAC,yBAAsB;AAEzC,6EAA6E;AAC7E,OAAO,EAAC,kBAAkB,EAAC,kCAA+B;AAC1D,uCAAuC;AACvC,OAAO,EAAC,qBAAqB,EAAC,qCAAkC"}
|
package/dist/lifecycle-test.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { makeSpy } from '@probe.gl/test-utils';
|
|
2
1
|
import type { Layer, Viewport } from '@deck.gl/core';
|
|
3
2
|
import type { Timeline } from '@luma.gl/engine';
|
|
4
3
|
type InitializeLayerTestOptions = {
|
|
@@ -39,7 +38,25 @@ export declare function testInitializeLayerAsync(opts: InitializeLayerTestOption
|
|
|
39
38
|
/** Finalize the layer and release all resources */
|
|
40
39
|
finalize: () => void;
|
|
41
40
|
}>;
|
|
42
|
-
|
|
41
|
+
/** Spy object compatible with both vitest and probe.gl */
|
|
42
|
+
export type Spy = {
|
|
43
|
+
/** Restore the original method (vitest) */
|
|
44
|
+
mockRestore?: () => void;
|
|
45
|
+
/** Restore the original method (probe.gl) */
|
|
46
|
+
restore?: () => void;
|
|
47
|
+
/** Call history (vitest) */
|
|
48
|
+
mock?: {
|
|
49
|
+
calls: unknown[][];
|
|
50
|
+
};
|
|
51
|
+
/** Call history (probe.gl) */
|
|
52
|
+
calls?: unknown[][];
|
|
53
|
+
/** Whether the spy was called (probe.gl) */
|
|
54
|
+
called?: boolean;
|
|
55
|
+
};
|
|
56
|
+
/** Factory function to create a spy on an object method */
|
|
57
|
+
export type SpyFactory = (obj: object, method: string) => Spy;
|
|
58
|
+
/** Function to reset/cleanup a spy after each test case */
|
|
59
|
+
export type ResetSpy = (spy: Spy) => void;
|
|
43
60
|
export type LayerClass<LayerT extends Layer> = {
|
|
44
61
|
new (...args: any[]): LayerT;
|
|
45
62
|
layerName: string;
|
|
@@ -69,11 +86,7 @@ export type LayerTestCase<LayerT extends Layer> = {
|
|
|
69
86
|
spies: Record<string, Spy>;
|
|
70
87
|
}) => void;
|
|
71
88
|
};
|
|
72
|
-
|
|
73
|
-
* Initialize and updates a layer over a sequence of scenarios (test cases).
|
|
74
|
-
* Use `testLayerAsync` if the layer's update flow contains async operations.
|
|
75
|
-
*/
|
|
76
|
-
export declare function testLayer<LayerT extends Layer>(opts: {
|
|
89
|
+
export type TestLayerOptions<LayerT extends Layer> = {
|
|
77
90
|
/** The layer class to test against */
|
|
78
91
|
Layer: LayerClass<LayerT>;
|
|
79
92
|
/** The initial viewport
|
|
@@ -91,29 +104,20 @@ export declare function testLayer<LayerT extends Layer>(opts: {
|
|
|
91
104
|
spies?: string[];
|
|
92
105
|
/** Callback if any error is thrown */
|
|
93
106
|
onError?: (error: Error, title: string) => void;
|
|
94
|
-
|
|
107
|
+
/** Factory function to create spies */
|
|
108
|
+
createSpy: SpyFactory;
|
|
109
|
+
/** Function to reset/cleanup a spy after each test case */
|
|
110
|
+
resetSpy: ResetSpy;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Initialize and updates a layer over a sequence of scenarios (test cases).
|
|
114
|
+
* Use `testLayerAsync` if the layer's update flow contains async operations.
|
|
115
|
+
*/
|
|
116
|
+
export declare function testLayer<LayerT extends Layer>(opts: TestLayerOptions<LayerT>): void;
|
|
95
117
|
/**
|
|
96
118
|
* Initialize and updates a layer over a sequence of scenarios (test cases).
|
|
97
119
|
* Each test case is awaited until the layer's isLoaded flag is true.
|
|
98
120
|
*/
|
|
99
|
-
export declare function testLayerAsync<LayerT extends Layer>(opts:
|
|
100
|
-
/** The layer class to test against */
|
|
101
|
-
Layer: LayerClass<LayerT>;
|
|
102
|
-
/** The initial viewport
|
|
103
|
-
* @default WebMercatorViewport
|
|
104
|
-
*/
|
|
105
|
-
viewport?: Viewport;
|
|
106
|
-
/**
|
|
107
|
-
* If provided, used to controls time progression. Useful for testing transitions and animations.
|
|
108
|
-
*/
|
|
109
|
-
timeline?: Timeline;
|
|
110
|
-
testCases?: LayerTestCase<LayerT>[];
|
|
111
|
-
/**
|
|
112
|
-
* List of layer method names to watch
|
|
113
|
-
*/
|
|
114
|
-
spies?: string[];
|
|
115
|
-
/** Callback if any error is thrown */
|
|
116
|
-
onError?: (error: Error, title: string) => void;
|
|
117
|
-
}): Promise<void>;
|
|
121
|
+
export declare function testLayerAsync<LayerT extends Layer>(opts: TestLayerOptions<LayerT>): Promise<void>;
|
|
118
122
|
export {};
|
|
119
123
|
//# sourceMappingURL=lifecycle-test.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle-test.d.ts","sourceRoot":"","sources":["../src/lifecycle-test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lifecycle-test.d.ts","sourceRoot":"","sources":["../src/lifecycle-test.ts"],"names":[],"mappings":"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"}
|