• 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

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

5
import type {
6
  DeviceProps,
7
  CanvasContextProps,
8
  PresentationContextProps,
9
  PresentationContext,
10
  VertexArray,
11
  VertexArrayProps,
12
  BufferProps,
13
  ShaderProps,
14
  SamplerProps,
15
  TextureProps,
16
  ExternalTexture,
17
  ExternalTextureProps,
18
  FramebufferProps,
19
  RenderPipelineProps,
20
  ComputePipeline,
21
  ComputePipelineProps,
22
  CommandEncoderProps,
23
  TransformFeedbackProps,
24
  QuerySetProps
25
} from '@luma.gl/core';
26
import {Device, DeviceFeatures} from '@luma.gl/core';
27
import type {NullCommandBuffer} from './resources/null-command-buffer';
28

29
import {NullDeviceInfo} from './null-device-info';
30
import {NullDeviceLimits} from './null-device-features';
31
import {NullCanvasContext} from './null-canvas-context';
32
import {NullBuffer} from './resources/null-buffer';
33
import {NullFramebuffer} from './resources/null-framebuffer';
34
import {NullShader} from './resources/null-shader';
35
import {NullCommandEncoder} from './resources/null-command-encoder';
36
import {NullSampler} from './resources/null-sampler';
37
import {NullTexture} from './resources/null-texture';
38
import {NullRenderPass} from './resources/null-render-pass';
39
import {NullRenderPipeline} from './resources/null-render-pipeline';
40
import {NullVertexArray} from './resources/null-vertex-array';
41
import {NullTransformFeedback} from './resources/null-transform-feedback';
42
import {NullQuerySet} from './resources/null-query-set';
43
import {NullFence} from './resources/null-fence';
44

45
/** Do-nothing device implementation for testing */
46
export class NullDevice extends Device {
47
  static isSupported(): boolean {
48
    return true;
×
49
  }
50
  readonly type = 'null';
10✔
51
  readonly handle = null;
10✔
52

53
  readonly preferredColorFormat = 'rgba8unorm';
10✔
54
  readonly preferredDepthFormat = 'depth24plus';
10✔
55

56
  features: DeviceFeatures = new DeviceFeatures([], this.props._disabledFeatures);
10✔
57
  limits: NullDeviceLimits = new NullDeviceLimits();
10✔
58
  readonly info = NullDeviceInfo;
10✔
59

60
  readonly canvasContext: NullCanvasContext;
61
  override commandEncoder: NullCommandEncoder;
62

63
  readonly lost: Promise<{reason: 'destroyed'; message: string}>;
64

65
  constructor(props: DeviceProps) {
66
    super({...props, id: props.id || 'null-device'});
10✔
67

68
    const canvasContextProps = Device._getCanvasContextProps(props);
10✔
69
    this.canvasContext = new NullCanvasContext(this, canvasContextProps);
10✔
70
    this.lost = new Promise(resolve => {});
10✔
71
    this.commandEncoder = new NullCommandEncoder(this, {id: 'null-command-encoder'});
10✔
72
  }
73

74
  /**
75
   * Destroys the context
76
   * @note Has no effect for null contexts
77
   */
78
  destroy(): void {
79
    this.commandEncoder?.destroy();
×
80
  }
81

82
  get isLost(): boolean {
83
    return false;
×
84
  }
85

86
  // IMPLEMENTATION OF ABSTRACT DEVICE
87

88
  createCanvasContext(props: CanvasContextProps): NullCanvasContext {
89
    return new NullCanvasContext(this, props);
×
90
  }
91

92
  createPresentationContext(_props?: PresentationContextProps): PresentationContext {
93
    throw new Error('PresentationContext is not supported on NullDevice');
1✔
94
  }
95

96
  createBuffer(props: BufferProps | ArrayBuffer | ArrayBufferView): NullBuffer {
97
    const newProps = this._normalizeBufferProps(props);
13✔
98
    return new NullBuffer(this, newProps);
13✔
99
  }
100

101
  getDefaultRenderPass(): NullRenderPass {
102
    return new NullRenderPass(this, {});
×
103
  }
104

105
  createTexture(props: TextureProps): NullTexture {
106
    return new NullTexture(this, props);
8✔
107
  }
108

109
  createExternalTexture(props: ExternalTextureProps): ExternalTexture {
110
    throw new Error('createExternalTexture() not implemented'); // return new Program(props);
×
111
  }
112

113
  createSampler(props: SamplerProps): NullSampler {
114
    return new NullSampler(this, props);
×
115
  }
116

117
  createShader(props: ShaderProps): NullShader {
118
    return new NullShader(this, props);
×
119
  }
120

121
  createFramebuffer(props: FramebufferProps): NullFramebuffer {
122
    return new NullFramebuffer(this, props);
×
123
  }
124

125
  createVertexArray(props: VertexArrayProps): VertexArray {
126
    return new NullVertexArray(this, props);
×
127
  }
128

129
  createTransformFeedback(props: TransformFeedbackProps): NullTransformFeedback {
130
    return new NullTransformFeedback(this, props);
×
131
  }
132

133
  createQuerySet(props: QuerySetProps): NullQuerySet {
134
    return new NullQuerySet(this, props);
×
135
  }
136

137
  override createFence(): NullFence {
138
    return new NullFence(this);
1✔
139
  }
140

141
  createRenderPipeline(props: RenderPipelineProps): NullRenderPipeline {
142
    return new NullRenderPipeline(this, props);
×
143
  }
144

145
  createComputePipeline(props?: ComputePipelineProps): ComputePipeline {
146
    throw new Error('ComputePipeline not supported in WebGL');
×
147
  }
148

149
  override createCommandEncoder(props: CommandEncoderProps = {}): NullCommandEncoder {
1✔
150
    return new NullCommandEncoder(this, props);
1✔
151
  }
152

153
  submit(commandBuffer?: NullCommandBuffer): void {
154
    if (!commandBuffer) {
1!
155
      commandBuffer = this.commandEncoder.finish({id: `${this.id}-default-command-buffer`});
×
156
      this.commandEncoder.destroy();
×
157
      this.commandEncoder = this.createCommandEncoder({id: `${this.id}-default-command-encoder`});
×
158
    }
159

160
    commandBuffer.destroy();
1✔
161
  }
162

163
  override setParametersWebGL(parameters: any): void {}
164

165
  override getParametersWebGL(parameters: any): any {}
166

167
  override withParametersWebGL(parameters: any, func: any): any {
168
    const {nocatch = true} = parameters;
×
169
    let value: any;
170
    if (nocatch) {
×
171
      // Avoid try catch to minimize stack size impact for safe execution paths
172
      return func();
×
173
    }
174
    // Wrap in a try-catch to ensure that parameters are restored on exceptions
175
    try {
×
176
      value = func();
×
177
    } catch {
178
      // ignore
179
    }
180
    return value;
×
181
  }
182

183
  override _getDeviceSpecificTextureFormatCapabilities(format: any): any {
184
    return format;
×
185
  }
186
}
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