• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / luma.gl / 23357510199

20 Mar 2026 06:40PM UTC coverage: 58.158% (+5.9%) from 52.213%
23357510199

push

github

web-flow
chore: Run tests on src instead of dist (#2555)

3021 of 6029 branches covered (50.11%)

Branch coverage included in aggregate %.

7102 of 11377 relevant lines covered (62.42%)

243.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.27
/modules/test-utils/src/create-test-device.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import type {Device, CanvasContextProps} from '@luma.gl/core';
6
import {luma, log} from '@luma.gl/core';
7
import {webgl2Adapter, WebGLDevice} from '@luma.gl/webgl';
8
import {webgpuAdapter, WebGPUDevice} from '@luma.gl/webgpu';
9
import {nullAdapter} from './null-device/null-adapter';
10
import {NullDevice} from './null-device/null-device';
11

12
const DEFAULT_CANVAS_CONTEXT_PROPS: CanvasContextProps = {width: 1, height: 1};
55✔
13

14
/** A null device intended for testing - @note Only available after getTestDevices() has completed */
15
let nullDevicePromise: Promise<NullDevice> | null = null;
55✔
16
/** This WebGL Device can be used directly but will not have WebGL debugging initialized */
17
let webglDevicePromise: Promise<WebGLDevice> | null = null;
55✔
18
/** A WebGL 2 Device intended for testing - @note Only available after getTestDevices() has completed */
19
let webgpuDevicePromise: Promise<WebGPUDevice | null> | null = null;
55✔
20

21
/** Includes WebGPU device if available */
22
export async function getTestDevices(
23
  types: Readonly<('webgl' | 'webgpu' | 'null' | 'unknown')[]> = ['webgl', 'webgpu']
63✔
24
): Promise<Device[]> {
25
  const promises = types.map(type => getTestDevice(type));
138✔
26
  const devices = await Promise.all(promises);
63✔
27
  return devices.filter(device => device !== null);
138✔
28
}
29

30
export async function getTestDevice(
31
  type: 'webgl' | 'webgpu' | 'null' | 'unknown'
32
): Promise<Device | null> {
33
  switch (type) {
138!
34
    case 'webgl':
35
      return getOrCreateWebGLTestDevicePromise();
62✔
36
    case 'webgpu':
37
      return getOrCreateWebGPUTestDevicePromise();
62✔
38
    case 'null':
39
      return getOrCreateNullTestDevicePromise();
14✔
40
    case 'unknown':
41
      return null;
×
42
  }
43
}
44

45
/** returns WebGPU device promise, if available */
46
export function getWebGPUTestDevice(): Promise<WebGPUDevice | null> {
47
  return getOrCreateWebGPUTestDevicePromise();
33✔
48
}
49

50
/** returns WebGL device promise, if available */
51
export async function getWebGLTestDevice(): Promise<WebGLDevice> {
52
  return getOrCreateWebGLTestDevicePromise();
135✔
53
}
54

55
/** returns null device promise, if available */
56
export async function getNullTestDevice(): Promise<NullDevice> {
57
  return getOrCreateNullTestDevicePromise();
10✔
58
}
59

60
function getOrCreateWebGPUTestDevicePromise(): Promise<WebGPUDevice | null> {
61
  webgpuDevicePromise ||= makeWebGPUTestDevice();
95✔
62
  return webgpuDevicePromise;
95✔
63
}
64

65
function getOrCreateWebGLTestDevicePromise(): Promise<WebGLDevice> {
66
  webglDevicePromise ||= makeWebGLTestDevice();
197✔
67
  return webglDevicePromise;
197✔
68
}
69

70
function getOrCreateNullTestDevicePromise(): Promise<NullDevice> {
71
  nullDevicePromise ||= makeNullTestDevice();
24✔
72
  return nullDevicePromise;
24✔
73
}
74

75
async function makeWebGPUTestDevice(): Promise<WebGPUDevice | null> {
76
  const webgpuDeviceResolvers = withResolvers<WebGPUDevice | null>();
23✔
77
  try {
23✔
78
    const webgpuDevice = (await luma.createDevice({
23✔
79
      id: 'webgpu-test-device',
80
      type: 'webgpu',
81
      adapters: [webgpuAdapter],
82
      createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
83
      debug: true
84
    })) as unknown as WebGPUDevice;
85
    webgpuDeviceResolvers.resolve(webgpuDevice);
×
86
  } catch (error) {
87
    log.error(String(error))();
23✔
88
    // @ts-ignore TODO
89
    webgpuDeviceResolvers.resolve(null);
23✔
90
  }
91
  return webgpuDeviceResolvers.promise;
23✔
92
}
93

94
/** returns WebGL device promise, if available */
95
async function makeWebGLTestDevice(): Promise<WebGLDevice> {
96
  const webglDeviceResolvers = withResolvers<WebGLDevice>();
45✔
97
  try {
45✔
98
    const webglDevice = (await luma.createDevice({
45✔
99
      id: 'webgl-test-device',
100
      type: 'webgl',
101
      adapters: [webgl2Adapter],
102
      createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
103
      debug: true
104
    })) as unknown as WebGLDevice;
105
    webglDeviceResolvers.resolve(webglDevice);
45✔
106
  } catch (error) {
107
    log.error(String(error))();
×
108
    // @ts-ignore TODO
109
    webglDeviceResolvers.resolve(null);
×
110
  }
111
  return webglDeviceResolvers.promise;
45✔
112
}
113

114
/** returns null device promise, if available */
115
async function makeNullTestDevice(): Promise<NullDevice> {
116
  const nullDeviceResolvers = withResolvers<NullDevice>();
7✔
117
  try {
7✔
118
    const nullDevice = (await luma.createDevice({
7✔
119
      id: 'null-test-device',
120
      type: 'null',
121
      adapters: [nullAdapter],
122
      createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
123
      debug: true
124
    })) as unknown as NullDevice;
125
    nullDeviceResolvers.resolve(nullDevice);
7✔
126
  } catch (error) {
127
    log.error(String(error))();
×
128
    // @ts-ignore TODO
129
    nullDevicePromise = Promise.resolve(null);
×
130
  }
131
  return nullDeviceResolvers.promise;
7✔
132
}
133

134
// HELPERS
135

136
// TODO - replace with Promise.withResolvers once we upgrade TS baseline
137
function withResolvers<T>(): {
138
  promise: Promise<T>;
139
  resolve: (t: T) => void;
140
  reject: (error: Error) => void;
141
} {
142
  let resolve;
143
  let reject;
144
  const promise = new Promise<T>((_resolve, _reject) => {
75✔
145
    resolve = _resolve;
75✔
146
    reject = _reject;
75✔
147
  });
148
  // @ts-ignore Assigned in callback.
149
  return {promise, resolve, reject};
75✔
150
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc