@deck.gl/test-utils 9.3.0-alpha.3 → 9.3.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -29,8 +29,8 @@ __export(dist_exports, {
29
29
  gl: () => gl,
30
30
  testInitializeLayer: () => testInitializeLayer,
31
31
  testInitializeLayerAsync: () => testInitializeLayerAsync,
32
- testLayer: () => testLayer,
33
- testLayerAsync: () => 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].reset());
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].reset());
147
+ Object.keys(spyMap).forEach((k) => resetSpy(spyMap[k]));
146
148
  layer = newLayer;
147
149
  }
148
- const error = cleanupAfterLayerTests(resources);
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
- const resourceCounts = getResourceCounts();
171
- for (const resourceName in resourceCounts) {
172
- if (resourceCounts[resourceName] !== oldResourceCounts[resourceName]) {
173
- return new Error(`${resourceCounts[resourceName] - oldResourceCounts[resourceName]} ${resourceName}s`);
174
- }
175
- }
176
- return null;
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 injectSpies(layer, spies) {
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] = (0, import_test_utils2.makeSpy)(Object.getPrototypeOf(layer), 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("Timeout");
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: "Timeout" });
590
+ if (typeof err === "string" && err.startsWith("Timeout")) {
591
+ this.fail({ error: err });
552
592
  }
553
593
  }
554
594
  }
@@ -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": ";;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;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;;;AC1BA,wBAAsC;AAE/B,IAAM,SAAS,iCAAe,IAAI,6BAAW,CAAA,CAAE;AARtD;AASO,IAAM,OAAK,0DAAa,OAAM;AAErC,WAAW,YAAY,WAAW,aAAa;;;ACP/C,kBAAkD;AAElD,IAAAA,qBAAsB;AAOtB,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;AA6CM,SAAU,UAAgC,MAkB/C;AACC,QAAM,EAAC,OAAO,YAAY,CAAA,GAAI,QAAQ,CAAA,GAAI,UAAU,eAAc,IAAI;AAEtE,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,mBAAmB,UAAU,WAAW,OAAO,KAAK;AAEtF,gCAA4B,UAAU,UAAU,UAAU,MAAM;AAGhE,WAAO,KAAK,MAAM,EAAE,QAAQ,OAAK,OAAO,CAAC,EAAE,MAAK,CAAE;AAClD,YAAQ;EACV;AAEA,QAAM,QAAQ,uBAAuB,SAAS;AAC9C,MAAI,OAAO;AACT,YAAQ,OAAO,GAAG,MAAM,uCAAuC;EACjE;AACF;AAMA,eAAsB,eAAqC,MAkB1D;AACC,QAAM,EAAC,OAAO,YAAY,CAAA,GAAI,QAAQ,CAAA,GAAI,UAAU,eAAc,IAAI;AAEtE,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,mBAAmB,UAAU,WAAW,OAAO,KAAK;AAEtF,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,OAAO,CAAC,EAAE,MAAK,CAAE;AAClD,YAAQ;EACV;AAEA,QAAM,QAAQ,uBAAuB,SAAS;AAC9C,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,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,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,YAAY,OAAc,OAAe;AAChD,QAAM,SAA8B,CAAA;AACpC,MAAI,OAAO;AACT,eAAW,gBAAgB,OAAO;AAChC,aAAO,YAAY,QAAI,4BAAQ,OAAO,eAAe,KAAK,GAAG,YAAY;IAC3E;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,OAAe;AAKf,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,KAAK;AACvC,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;;;ACjbA,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,SAAS;MAClB,GAAG,OAAO;IACZ,CAAC;AAED,QAAI;AACF,YAAM,QAAQ,KAAK,CAAC,MAAM,WAAW,CAAC;AACtC,YAAM,KAAK,OAAO,QAAQ;IAC5B,SAAS,KAAP;AACA,UAAI,QAAQ,WAAW;AACrB,aAAK,KAAK,EAAC,OAAO,UAAS,CAAC;MAC9B;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": ["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": "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",
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 "./lifecycle-test.js";
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 "./lifecycle-test.js";
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
@@ -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;AAG5C,OAAO,EACL,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACzB,4BAAyB;AAC1B,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,EAAC,4BAAyB;AACpD,YAAY,EAAC,gBAAgB,EAAC,kCAA+B;AAC7D,YAAY,EAAC,mBAAmB,EAAC,qCAAkC"}
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 { testLayer, testLayerAsync, testInitializeLayer, testInitializeLayerAsync } from "./lifecycle-test.js";
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,EACL,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACzB,4BAAyB;AAC1B,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"}
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"}
@@ -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
- type Spy = ReturnType<typeof makeSpy>;
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
- }): void;
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":"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"}
1
+ {"version":3,"file":"lifecycle-test.d.ts","sourceRoot":"","sources":["../src/lifecycle-test.ts"],"names":[],"mappings":"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"}