@deck.gl/test-utils 9.0.0-beta.1 → 9.0.0-beta.10
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/generate-layer-tests.d.ts +20 -0
- package/dist/generate-layer-tests.d.ts.map +1 -0
- package/dist/generate-layer-tests.js +209 -0
- package/dist/index.cjs +645 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/interaction-test-runner.d.ts +29 -0
- package/dist/interaction-test-runner.d.ts.map +1 -0
- package/dist/interaction-test-runner.js +57 -0
- package/dist/lifecycle-test.d.ts +119 -0
- package/dist/lifecycle-test.d.ts.map +1 -0
- package/dist/lifecycle-test.js +232 -0
- package/dist/snapshot-test-runner.d.ts +46 -0
- package/dist/snapshot-test-runner.d.ts.map +1 -0
- package/dist/snapshot-test-runner.js +101 -0
- package/dist/test-runner.d.ts +56 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +143 -0
- package/dist/utils/dom.d.ts +7 -0
- package/dist/utils/dom.d.ts.map +1 -0
- package/dist/utils/dom.js +11 -0
- package/dist/utils/precision.d.ts +4 -0
- package/dist/utils/precision.d.ts.map +1 -0
- package/dist/utils/precision.js +19 -0
- package/dist/utils/setup-gl.d.ts +5 -0
- package/dist/utils/setup-gl.d.ts.map +1 -0
- package/dist/utils/setup-gl.js +15 -0
- package/package.json +17 -8
- package/src/generate-layer-tests.ts +54 -15
- package/src/index.ts +7 -3
- package/src/interaction-test-runner.ts +29 -13
- package/src/lifecycle-test.ts +214 -27
- package/src/snapshot-test-runner.ts +79 -47
- package/src/test-runner.ts +77 -59
- package/src/utils/dom.ts +6 -1
- package/src/utils/precision.ts +13 -6
- package/src/utils/setup-gl.ts +2 -2
- package/dist/es5/generate-layer-tests.js +0 -243
- package/dist/es5/generate-layer-tests.js.map +0 -1
- package/dist/es5/index.js +0 -88
- package/dist/es5/index.js.map +0 -1
- package/dist/es5/interaction-test-runner.js +0 -119
- package/dist/es5/interaction-test-runner.js.map +0 -1
- package/dist/es5/lifecycle-test.js +0 -456
- package/dist/es5/lifecycle-test.js.map +0 -1
- package/dist/es5/snapshot-test-runner.js +0 -145
- package/dist/es5/snapshot-test-runner.js.map +0 -1
- package/dist/es5/test-runner.js +0 -198
- package/dist/es5/test-runner.js.map +0 -1
- package/dist/es5/utils/dom.js +0 -17
- package/dist/es5/utils/dom.js.map +0 -1
- package/dist/es5/utils/precision.js +0 -33
- package/dist/es5/utils/precision.js.map +0 -1
- package/dist/es5/utils/setup-gl.js +0 -19
- package/dist/es5/utils/setup-gl.js.map +0 -1
- package/dist/esm/generate-layer-tests.js +0 -216
- package/dist/esm/generate-layer-tests.js.map +0 -1
- package/dist/esm/index.js +0 -8
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/interaction-test-runner.js +0 -52
- package/dist/esm/interaction-test-runner.js.map +0 -1
- package/dist/esm/lifecycle-test.js +0 -282
- package/dist/esm/lifecycle-test.js.map +0 -1
- package/dist/esm/snapshot-test-runner.js +0 -94
- package/dist/esm/snapshot-test-runner.js.map +0 -1
- package/dist/esm/test-runner.js +0 -134
- package/dist/esm/test-runner.js.map +0 -1
- package/dist/esm/utils/dom.js +0 -10
- package/dist/esm/utils/dom.js.map +0 -1
- package/dist/esm/utils/precision.js +0 -18
- package/dist/esm/utils/precision.js.map +0 -1
- package/dist/esm/utils/setup-gl.js +0 -9
- package/dist/esm/utils/setup-gl.js.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// dist/index.js
|
|
21
|
+
var dist_exports = {};
|
|
22
|
+
__export(dist_exports, {
|
|
23
|
+
InteractionTestRunner: () => InteractionTestRunner,
|
|
24
|
+
SnapshotTestRunner: () => SnapshotTestRunner,
|
|
25
|
+
TestRunner: () => TestRunner,
|
|
26
|
+
device: () => device,
|
|
27
|
+
generateLayerTests: () => generateLayerTests,
|
|
28
|
+
gl: () => gl,
|
|
29
|
+
testInitializeLayer: () => testInitializeLayer,
|
|
30
|
+
testInitializeLayerAsync: () => testInitializeLayerAsync,
|
|
31
|
+
testLayer: () => testLayer,
|
|
32
|
+
testLayerAsync: () => testLayerAsync,
|
|
33
|
+
toLowPrecision: () => toLowPrecision
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(dist_exports);
|
|
36
|
+
|
|
37
|
+
// dist/utils/precision.js
|
|
38
|
+
function toLowPrecision(input, precision = 11) {
|
|
39
|
+
if (typeof input === "number") {
|
|
40
|
+
return Number(input.toPrecision(precision));
|
|
41
|
+
}
|
|
42
|
+
if (Array.isArray(input)) {
|
|
43
|
+
return input.map((item) => toLowPrecision(item, precision));
|
|
44
|
+
}
|
|
45
|
+
if (typeof input === "object") {
|
|
46
|
+
for (const key in input) {
|
|
47
|
+
input[key] = toLowPrecision(input[key], precision);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return input;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// dist/utils/setup-gl.js
|
|
54
|
+
var import_test_utils = require("@luma.gl/test-utils");
|
|
55
|
+
var device = import_test_utils.webglDevice;
|
|
56
|
+
var gl = (0, import_test_utils.createTestContext)({
|
|
57
|
+
width: 1,
|
|
58
|
+
height: 1,
|
|
59
|
+
debug: true
|
|
60
|
+
});
|
|
61
|
+
globalThis.glContext = globalThis.glContext || gl;
|
|
62
|
+
|
|
63
|
+
// dist/lifecycle-test.js
|
|
64
|
+
var import_core = require("@deck.gl/core");
|
|
65
|
+
var import_test_utils2 = require("@probe.gl/test-utils");
|
|
66
|
+
var testViewport = new import_core.MapView({}).makeViewport({
|
|
67
|
+
width: 100,
|
|
68
|
+
height: 100,
|
|
69
|
+
viewState: { longitude: 0, latitude: 0, zoom: 1 }
|
|
70
|
+
});
|
|
71
|
+
function defaultOnError(error, title) {
|
|
72
|
+
if (error) {
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function initializeLayerManager({ layer, viewport = testViewport, onError = defaultOnError }) {
|
|
77
|
+
const layerManager = new import_core.LayerManager(device, { viewport });
|
|
78
|
+
layerManager.setProps({
|
|
79
|
+
onError: (error) => onError(error, `initializing ${layer.id}`)
|
|
80
|
+
});
|
|
81
|
+
layerManager.setLayers([layer]);
|
|
82
|
+
return layerManager;
|
|
83
|
+
}
|
|
84
|
+
function testInitializeLayer(opts) {
|
|
85
|
+
const layerManager = initializeLayerManager(opts);
|
|
86
|
+
if (opts.finalize === false) {
|
|
87
|
+
return {
|
|
88
|
+
finalize: () => layerManager.finalize()
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
layerManager.finalize();
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
async function testInitializeLayerAsync(opts) {
|
|
95
|
+
const layerManager = initializeLayerManager(opts);
|
|
96
|
+
const deckRenderer = new import_core.DeckRenderer(device);
|
|
97
|
+
while (!opts.layer.isLoaded) {
|
|
98
|
+
await update({ layerManager, deckRenderer, oldResourceCounts: {} });
|
|
99
|
+
}
|
|
100
|
+
if (opts.finalize === false) {
|
|
101
|
+
return {
|
|
102
|
+
finalize: () => layerManager.finalize()
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
layerManager.finalize();
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
function testLayer(opts) {
|
|
109
|
+
const { Layer, testCases = [], spies = [], onError = defaultOnError } = opts;
|
|
110
|
+
const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);
|
|
111
|
+
let layer = new Layer();
|
|
112
|
+
for (const testCase of testCases) {
|
|
113
|
+
const oldState = { ...layer.state };
|
|
114
|
+
const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies);
|
|
115
|
+
runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
|
|
116
|
+
Object.keys(spyMap).forEach((k) => spyMap[k].reset());
|
|
117
|
+
layer = newLayer;
|
|
118
|
+
}
|
|
119
|
+
const error = cleanupAfterLayerTests(resources);
|
|
120
|
+
if (error) {
|
|
121
|
+
onError(error, `${Layer.layerName} should delete all resources`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function testLayerAsync(opts) {
|
|
125
|
+
const { Layer, testCases = [], spies = [], onError = defaultOnError } = opts;
|
|
126
|
+
const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);
|
|
127
|
+
let layer = new Layer();
|
|
128
|
+
for (const testCase of testCases) {
|
|
129
|
+
const oldState = { ...layer.state };
|
|
130
|
+
const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies);
|
|
131
|
+
runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
|
|
132
|
+
while (!newLayer.isLoaded) {
|
|
133
|
+
await update(resources);
|
|
134
|
+
runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
|
|
135
|
+
}
|
|
136
|
+
Object.keys(spyMap).forEach((k) => spyMap[k].reset());
|
|
137
|
+
layer = newLayer;
|
|
138
|
+
}
|
|
139
|
+
const error = cleanupAfterLayerTests(resources);
|
|
140
|
+
if (error) {
|
|
141
|
+
onError(error, `${Layer.layerName} should delete all resources`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function setupLayerTests(testTitle, { viewport = testViewport, timeline, onError = defaultOnError }) {
|
|
145
|
+
const oldResourceCounts = getResourceCounts();
|
|
146
|
+
const layerManager = new import_core.LayerManager(device, { viewport, timeline });
|
|
147
|
+
const deckRenderer = new import_core.DeckRenderer(device);
|
|
148
|
+
const props = {
|
|
149
|
+
layerFilter: null,
|
|
150
|
+
drawPickingColors: false,
|
|
151
|
+
onError: (error) => onError(error, testTitle)
|
|
152
|
+
};
|
|
153
|
+
layerManager.setProps(props);
|
|
154
|
+
deckRenderer.setProps(props);
|
|
155
|
+
return { layerManager, deckRenderer, oldResourceCounts };
|
|
156
|
+
}
|
|
157
|
+
function cleanupAfterLayerTests({ layerManager, deckRenderer, oldResourceCounts }) {
|
|
158
|
+
layerManager.setLayers([]);
|
|
159
|
+
layerManager.finalize();
|
|
160
|
+
deckRenderer.finalize();
|
|
161
|
+
const resourceCounts = getResourceCounts();
|
|
162
|
+
for (const resourceName in resourceCounts) {
|
|
163
|
+
if (resourceCounts[resourceName] !== oldResourceCounts[resourceName]) {
|
|
164
|
+
return new Error(`${resourceCounts[resourceName] - oldResourceCounts[resourceName]} ${resourceName}s`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
function getResourceCounts() {
|
|
170
|
+
const resourceStats = luma.stats.get("Resource Counts");
|
|
171
|
+
return {
|
|
172
|
+
Texture2D: resourceStats.get("Texture2Ds Active").count,
|
|
173
|
+
Buffer: resourceStats.get("Buffers Active").count
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function injectSpies(layer, spies) {
|
|
177
|
+
const spyMap = {};
|
|
178
|
+
if (spies) {
|
|
179
|
+
for (const functionName of spies) {
|
|
180
|
+
spyMap[functionName] = (0, import_test_utils2.makeSpy)(Object.getPrototypeOf(layer), functionName);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return spyMap;
|
|
184
|
+
}
|
|
185
|
+
function runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap) {
|
|
186
|
+
if (testCase.onAfterUpdate) {
|
|
187
|
+
const subLayers = newLayer.isComposite ? newLayer.getSubLayers() : [];
|
|
188
|
+
const subLayer = subLayers.length ? subLayers[0] : null;
|
|
189
|
+
testCase.onAfterUpdate({
|
|
190
|
+
testCase,
|
|
191
|
+
layer: newLayer,
|
|
192
|
+
oldState,
|
|
193
|
+
subLayers,
|
|
194
|
+
subLayer,
|
|
195
|
+
spies: spyMap
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function runLayerTestUpdate(testCase, { layerManager, deckRenderer }, layer, spies) {
|
|
200
|
+
const { props, updateProps, onBeforeUpdate, viewport = layerManager.context.viewport } = testCase;
|
|
201
|
+
if (onBeforeUpdate) {
|
|
202
|
+
onBeforeUpdate({ layer, testCase });
|
|
203
|
+
}
|
|
204
|
+
if (props) {
|
|
205
|
+
layer = new layer.constructor(props);
|
|
206
|
+
} else if (updateProps) {
|
|
207
|
+
layer = layer.clone(updateProps);
|
|
208
|
+
}
|
|
209
|
+
spies = testCase.spies || spies;
|
|
210
|
+
const spyMap = injectSpies(layer, spies);
|
|
211
|
+
const drawLayers = () => {
|
|
212
|
+
deckRenderer.renderLayers({
|
|
213
|
+
pass: "test",
|
|
214
|
+
views: {},
|
|
215
|
+
effects: [],
|
|
216
|
+
viewports: [viewport],
|
|
217
|
+
layers: layerManager.getLayers(),
|
|
218
|
+
onViewportActive: layerManager.activateViewport
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
layerManager.setLayers([layer]);
|
|
222
|
+
drawLayers();
|
|
223
|
+
if (layerManager.needsUpdate()) {
|
|
224
|
+
layerManager.updateLayers();
|
|
225
|
+
drawLayers();
|
|
226
|
+
}
|
|
227
|
+
return { layer, spyMap };
|
|
228
|
+
}
|
|
229
|
+
function update({ layerManager, deckRenderer }) {
|
|
230
|
+
return new Promise((resolve) => {
|
|
231
|
+
const onAnimationFrame = () => {
|
|
232
|
+
if (layerManager.needsUpdate()) {
|
|
233
|
+
layerManager.updateLayers();
|
|
234
|
+
deckRenderer.renderLayers({
|
|
235
|
+
pass: "test",
|
|
236
|
+
views: {},
|
|
237
|
+
effects: [],
|
|
238
|
+
viewports: [layerManager.context.viewport],
|
|
239
|
+
layers: layerManager.getLayers(),
|
|
240
|
+
onViewportActive: layerManager.activateViewport
|
|
241
|
+
});
|
|
242
|
+
resolve();
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
setTimeout(onAnimationFrame, 50);
|
|
246
|
+
};
|
|
247
|
+
onAnimationFrame();
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// dist/generate-layer-tests.js
|
|
252
|
+
var import_core2 = require("@deck.gl/core");
|
|
253
|
+
function noop() {
|
|
254
|
+
}
|
|
255
|
+
function defaultAssert(condition, comment) {
|
|
256
|
+
if (!condition) {
|
|
257
|
+
throw new Error(comment);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function generateLayerTests({ Layer, sampleProps = {}, assert = defaultAssert, onBeforeUpdate = noop, onAfterUpdate = noop, runDefaultAsserts = true }) {
|
|
261
|
+
assert(Layer.layerName, "Layer should have display name");
|
|
262
|
+
function wrapTestCaseTitle(title) {
|
|
263
|
+
return `${Layer.layerName}#${title}`;
|
|
264
|
+
}
|
|
265
|
+
const testCases = [
|
|
266
|
+
{
|
|
267
|
+
title: "Empty props",
|
|
268
|
+
props: {}
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
title: "Null data",
|
|
272
|
+
updateProps: { data: null }
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
title: "Sample data",
|
|
276
|
+
updateProps: sampleProps
|
|
277
|
+
}
|
|
278
|
+
];
|
|
279
|
+
try {
|
|
280
|
+
new Layer({});
|
|
281
|
+
} catch (error) {
|
|
282
|
+
assert(false, `Construct ${Layer.layerName} throws: ${error.message}`);
|
|
283
|
+
}
|
|
284
|
+
const { _propTypes: propTypes, _mergedDefaultProps: defaultProps } = Layer;
|
|
285
|
+
testCases.push(...makeAltDataTestCases(sampleProps, propTypes));
|
|
286
|
+
for (const propName in Layer.defaultProps) {
|
|
287
|
+
if (!(propName in sampleProps)) {
|
|
288
|
+
const newTestCase = makeAltPropTestCase({ propName, propTypes, defaultProps, sampleProps, assert }) || [];
|
|
289
|
+
testCases.push(...newTestCase);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
testCases.forEach((testCase) => {
|
|
293
|
+
testCase.title = wrapTestCaseTitle(testCase.title);
|
|
294
|
+
const beforeFunc = testCase.onBeforeUpdate || noop;
|
|
295
|
+
const afterFunc = testCase.onAfterUpdate || noop;
|
|
296
|
+
testCase.onBeforeUpdate = (params) => {
|
|
297
|
+
beforeFunc(params);
|
|
298
|
+
onBeforeUpdate(params);
|
|
299
|
+
};
|
|
300
|
+
testCase.onAfterUpdate = (params) => {
|
|
301
|
+
afterFunc(params);
|
|
302
|
+
onAfterUpdate(params);
|
|
303
|
+
if (runDefaultAsserts) {
|
|
304
|
+
if (params.layer.isComposite) {
|
|
305
|
+
const { data } = params.layer.props;
|
|
306
|
+
if (data && typeof data === "object" && (0, import_core2._count)(data)) {
|
|
307
|
+
assert(params.subLayers.length, "Layer should have sublayers");
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
assert(params.layer.getModels().length, "Layer should have models");
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
return testCases;
|
|
316
|
+
}
|
|
317
|
+
function makeAltPropTestCase({ propName, propTypes, defaultProps, sampleProps, assert }) {
|
|
318
|
+
const newProps = { ...sampleProps };
|
|
319
|
+
const propDef = propTypes[propName];
|
|
320
|
+
if (!propDef) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
switch (propDef.type) {
|
|
324
|
+
case "boolean":
|
|
325
|
+
newProps[propName] = !defaultProps[propName];
|
|
326
|
+
return [
|
|
327
|
+
{
|
|
328
|
+
title: `${propName}: ${String(newProps[propName])}`,
|
|
329
|
+
props: newProps
|
|
330
|
+
}
|
|
331
|
+
];
|
|
332
|
+
case "number":
|
|
333
|
+
if ("max" in propDef) {
|
|
334
|
+
newProps[propName] = propDef.max;
|
|
335
|
+
} else if ("min" in propDef) {
|
|
336
|
+
newProps[propName] = propDef.min;
|
|
337
|
+
} else {
|
|
338
|
+
newProps[propName] = defaultProps[propName] + 1;
|
|
339
|
+
}
|
|
340
|
+
return [
|
|
341
|
+
{
|
|
342
|
+
title: `${propName}: ${String(newProps[propName])}`,
|
|
343
|
+
props: newProps
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
case "accessor": {
|
|
347
|
+
if (typeof defaultProps[propName] === "function") {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
let callCount = 0;
|
|
351
|
+
newProps[propName] = () => {
|
|
352
|
+
callCount++;
|
|
353
|
+
return defaultProps[propName];
|
|
354
|
+
};
|
|
355
|
+
newProps.updateTriggers = {
|
|
356
|
+
[propName]: "function"
|
|
357
|
+
};
|
|
358
|
+
const onBeforeUpdate = () => callCount = 0;
|
|
359
|
+
const onAfterUpdate = () => assert(callCount > 0, "accessor function is called");
|
|
360
|
+
return [
|
|
361
|
+
{
|
|
362
|
+
title: `${propName}: () => ${defaultProps[propName]}`,
|
|
363
|
+
props: newProps,
|
|
364
|
+
onBeforeUpdate,
|
|
365
|
+
onAfterUpdate
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
title: `${propName}: updateTrigger`,
|
|
369
|
+
updateProps: {
|
|
370
|
+
updateTriggers: {
|
|
371
|
+
[propName]: "function+trigger"
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
onBeforeUpdate,
|
|
375
|
+
onAfterUpdate
|
|
376
|
+
}
|
|
377
|
+
];
|
|
378
|
+
}
|
|
379
|
+
default:
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function makeAltDataTestCases(props, propTypes) {
|
|
384
|
+
const originalData = props.data;
|
|
385
|
+
if (!Array.isArray(originalData)) {
|
|
386
|
+
return [];
|
|
387
|
+
}
|
|
388
|
+
const partialUpdateProps = {
|
|
389
|
+
data: originalData.slice(),
|
|
390
|
+
_dataDiff: () => [{ startRow: 0, endRow: 2 }]
|
|
391
|
+
};
|
|
392
|
+
const genIterableProps = {
|
|
393
|
+
data: new Set(originalData),
|
|
394
|
+
_dataDiff: null
|
|
395
|
+
};
|
|
396
|
+
const nonIterableProps = {
|
|
397
|
+
data: {
|
|
398
|
+
length: originalData.length
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
for (const propName in props) {
|
|
402
|
+
if (propTypes[propName].type === "accessor") {
|
|
403
|
+
nonIterableProps[propName] = (_, info) => props[propName](originalData[info.index], info);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return [
|
|
407
|
+
{
|
|
408
|
+
title: "Partial update",
|
|
409
|
+
updateProps: partialUpdateProps
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
title: "Generic iterable data",
|
|
413
|
+
updateProps: genIterableProps
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
title: "non-iterable data",
|
|
417
|
+
updateProps: nonIterableProps
|
|
418
|
+
}
|
|
419
|
+
];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// dist/test-runner.js
|
|
423
|
+
var import_core3 = require("@deck.gl/core");
|
|
424
|
+
var DEFAULT_DECK_PROPS = {
|
|
425
|
+
...import_core3.Deck.defaultProps,
|
|
426
|
+
id: "deckgl-render-test",
|
|
427
|
+
width: 800,
|
|
428
|
+
height: 450,
|
|
429
|
+
style: { position: "absolute", left: "0px", top: "0px" },
|
|
430
|
+
views: [new import_core3.MapView({})],
|
|
431
|
+
useDevicePixels: false,
|
|
432
|
+
debug: true
|
|
433
|
+
};
|
|
434
|
+
var DEFAULT_TEST_OPTIONS = {
|
|
435
|
+
onTestStart: (testCase) => console.log(`# ${testCase.name}`),
|
|
436
|
+
onTestPass: (testCase) => console.log(`ok ${testCase.name} passed`),
|
|
437
|
+
onTestFail: (testCase) => console.log(`not ok ${testCase.name} failed`),
|
|
438
|
+
timeout: 2e3
|
|
439
|
+
};
|
|
440
|
+
var TestRunner = class {
|
|
441
|
+
constructor(props = {}, options) {
|
|
442
|
+
this.deck = null;
|
|
443
|
+
this.isRunning = false;
|
|
444
|
+
this._testCases = [];
|
|
445
|
+
this._currentTestCase = null;
|
|
446
|
+
this._testCaseData = null;
|
|
447
|
+
this.props = { ...DEFAULT_DECK_PROPS, ...props };
|
|
448
|
+
this.isHeadless = Boolean(window.browserTestDriver_isHeadless);
|
|
449
|
+
this.testOptions = { ...DEFAULT_TEST_OPTIONS, ...options };
|
|
450
|
+
}
|
|
451
|
+
get defaultTestCase() {
|
|
452
|
+
throw new Error("Not implemented");
|
|
453
|
+
}
|
|
454
|
+
add(testCases) {
|
|
455
|
+
if (!Array.isArray(testCases)) {
|
|
456
|
+
testCases = [testCases];
|
|
457
|
+
}
|
|
458
|
+
for (const testCase of testCases) {
|
|
459
|
+
this._testCases.push(testCase);
|
|
460
|
+
}
|
|
461
|
+
return this;
|
|
462
|
+
}
|
|
463
|
+
run(options = {}) {
|
|
464
|
+
Object.assign(this.testOptions, options);
|
|
465
|
+
return new Promise((resolve, reject) => {
|
|
466
|
+
this.deck = new import_core3.Deck({
|
|
467
|
+
...this.props,
|
|
468
|
+
onDeviceInitialized: this._onDeviceInitialized.bind(this),
|
|
469
|
+
onLoad: resolve
|
|
470
|
+
});
|
|
471
|
+
this.isRunning = true;
|
|
472
|
+
this._currentTestCase = null;
|
|
473
|
+
}).then(() => {
|
|
474
|
+
let promise = Promise.resolve();
|
|
475
|
+
this._testCases.forEach((testCase) => {
|
|
476
|
+
promise = promise.then(() => this._runTest(testCase));
|
|
477
|
+
});
|
|
478
|
+
return promise;
|
|
479
|
+
}).catch((error) => {
|
|
480
|
+
this.fail({ error: error.message });
|
|
481
|
+
}).finally(() => {
|
|
482
|
+
this.deck.finalize();
|
|
483
|
+
this.deck = null;
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
initTestCase(testCase) {
|
|
487
|
+
for (const key in this.defaultTestCase) {
|
|
488
|
+
if (!(key in testCase)) {
|
|
489
|
+
testCase[key] = this.defaultTestCase[key];
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
this.testOptions.onTestStart(testCase);
|
|
493
|
+
}
|
|
494
|
+
pass(result) {
|
|
495
|
+
this.testOptions.onTestPass(this._currentTestCase, result);
|
|
496
|
+
}
|
|
497
|
+
fail(result) {
|
|
498
|
+
this.testOptions.onTestFail(this._currentTestCase, result);
|
|
499
|
+
}
|
|
500
|
+
_onDeviceInitialized(device2) {
|
|
501
|
+
this.gpuVendor = device2.info.vendor;
|
|
502
|
+
}
|
|
503
|
+
async _runTest(testCase) {
|
|
504
|
+
this._currentTestCase = testCase;
|
|
505
|
+
this.initTestCase(testCase);
|
|
506
|
+
const timeout = testCase.timeout || this.testOptions.timeout;
|
|
507
|
+
const task = this.runTestCase(testCase);
|
|
508
|
+
const timeoutTask = new Promise((_, reject) => {
|
|
509
|
+
setTimeout(() => {
|
|
510
|
+
reject("Timeout");
|
|
511
|
+
}, timeout);
|
|
512
|
+
});
|
|
513
|
+
try {
|
|
514
|
+
await Promise.race([task, timeoutTask]);
|
|
515
|
+
await this.assert(testCase);
|
|
516
|
+
} catch (err) {
|
|
517
|
+
if (err === "Timeout") {
|
|
518
|
+
this.fail({ error: "Timeout" });
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
// dist/utils/dom.js
|
|
525
|
+
function getBoundingBoxInPage(domElement) {
|
|
526
|
+
const bbox = domElement.getBoundingClientRect();
|
|
527
|
+
return {
|
|
528
|
+
x: window.scrollX + bbox.x,
|
|
529
|
+
y: window.scrollY + bbox.y,
|
|
530
|
+
width: bbox.width,
|
|
531
|
+
height: bbox.height
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// dist/snapshot-test-runner.js
|
|
536
|
+
var DEFAULT_TEST_OPTIONS2 = {
|
|
537
|
+
imageDiffOptions: {}
|
|
538
|
+
};
|
|
539
|
+
var DEFAULT_TEST_CASE = {
|
|
540
|
+
name: "Unnamed snapshot test",
|
|
541
|
+
props: {},
|
|
542
|
+
onBeforeRender: ({ deck, layers }) => {
|
|
543
|
+
},
|
|
544
|
+
onAfterRender: ({ deck, layers, done }) => {
|
|
545
|
+
if (layers.every((layer) => layer.isLoaded)) {
|
|
546
|
+
done();
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
goldenImage: ""
|
|
550
|
+
};
|
|
551
|
+
var SnapshotTestRunner = class extends TestRunner {
|
|
552
|
+
constructor(props) {
|
|
553
|
+
super(props, DEFAULT_TEST_OPTIONS2);
|
|
554
|
+
this._isDiffing = false;
|
|
555
|
+
this._isDiffing = false;
|
|
556
|
+
}
|
|
557
|
+
get defaultTestCase() {
|
|
558
|
+
return DEFAULT_TEST_CASE;
|
|
559
|
+
}
|
|
560
|
+
initTestCase(testCase) {
|
|
561
|
+
super.initTestCase(testCase);
|
|
562
|
+
if (!testCase.goldenImage) {
|
|
563
|
+
throw new Error(`Test case ${testCase.name} does not have golden image`);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
runTestCase(testCase) {
|
|
567
|
+
const deck = this.deck;
|
|
568
|
+
return new Promise((resolve) => {
|
|
569
|
+
deck.setProps({
|
|
570
|
+
...this.props,
|
|
571
|
+
...testCase,
|
|
572
|
+
onBeforeRender: () => {
|
|
573
|
+
testCase.onBeforeRender({
|
|
574
|
+
deck,
|
|
575
|
+
layers: this.deck.layerManager.getLayers()
|
|
576
|
+
});
|
|
577
|
+
},
|
|
578
|
+
onAfterRender: () => {
|
|
579
|
+
testCase.onAfterRender({
|
|
580
|
+
deck,
|
|
581
|
+
layers: this.deck.layerManager.getLayers(),
|
|
582
|
+
done: resolve
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
async assert(testCase) {
|
|
589
|
+
if (this._isDiffing) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
this._isDiffing = true;
|
|
593
|
+
const diffOptions = {
|
|
594
|
+
...this.testOptions.imageDiffOptions,
|
|
595
|
+
...testCase.imageDiffOptions,
|
|
596
|
+
goldenImage: testCase.goldenImage,
|
|
597
|
+
region: getBoundingBoxInPage(this.deck.getCanvas())
|
|
598
|
+
};
|
|
599
|
+
const result = await window.browserTestDriver_captureAndDiffScreen(diffOptions);
|
|
600
|
+
if (result.success) {
|
|
601
|
+
this.pass(result);
|
|
602
|
+
} else {
|
|
603
|
+
this.fail(result);
|
|
604
|
+
}
|
|
605
|
+
this._isDiffing = false;
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
// dist/interaction-test-runner.js
|
|
610
|
+
var DEFAULT_TEST_CASE2 = {
|
|
611
|
+
name: "Unnamed interaction test",
|
|
612
|
+
events: [],
|
|
613
|
+
onBeforeEvents: ({ deck }) => {
|
|
614
|
+
},
|
|
615
|
+
onAfterEvents: ({ deck, layers, context }) => {
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
function sleep(timeout) {
|
|
619
|
+
return new Promise((resolve) => window.setTimeout(resolve, timeout));
|
|
620
|
+
}
|
|
621
|
+
var InteractionTestRunner = class extends TestRunner {
|
|
622
|
+
get defaultTestCase() {
|
|
623
|
+
return DEFAULT_TEST_CASE2;
|
|
624
|
+
}
|
|
625
|
+
async runTestCase(testCase) {
|
|
626
|
+
testCase.context = testCase.onBeforeEvents({
|
|
627
|
+
deck: this.deck
|
|
628
|
+
});
|
|
629
|
+
for (const event of testCase.events) {
|
|
630
|
+
if (event.wait) {
|
|
631
|
+
await sleep(event.wait);
|
|
632
|
+
} else {
|
|
633
|
+
await window.browserTestDriver_emulateInput(event);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
async assert(testCase) {
|
|
638
|
+
testCase.onAfterEvents({
|
|
639
|
+
deck: this.deck,
|
|
640
|
+
layers: this.deck.layerManager.getLayers(),
|
|
641
|
+
context: testCase.context
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
//# sourceMappingURL=index.cjs.map
|