diff --git a/docs/api-reference/test-utils/generate-layer-tests.md b/docs/api-reference/test-utils/generate-layer-tests.md index f7162ac7fd2..9bac79c3864 100644 --- a/docs/api-reference/test-utils/generate-layer-tests.md +++ b/docs/api-reference/test-utils/generate-layer-tests.md @@ -2,9 +2,32 @@ This utility generates a series of test cases to be used with [testLayer](../test-utils/test-layer.md) that checks the conformance of a layer class. -## Example +## Example (Vitest) -Example of layer unit tests using `tape`. The test utility itself is test framework agnostic. +```ts +import {test, expect} from 'vitest'; +import {testLayer, generateLayerTests} from '@deck.gl/test-utils/vitest'; +import {GeoJsonLayer} from '@deck.gl/layers'; + +test('GeoJsonLayer#conformance', () => { + const testCases = generateLayerTests({ + Layer: GeoJsonLayer, + sampleProps: { + data: SAMPLE_GEOJSON + }, + assert: (cond, msg) => expect(cond, msg).toBeTruthy(), + onAfterUpdate: ({layer, subLayers}) => { + expect(layer.state.features).toBeTruthy(); + const expected = layer.props.stroked ? 2 : 1; + expect(subLayers.length).toBe(expected); + } + }); + + testLayer({Layer: GeoJsonLayer, testCases, onError: err => expect(err).toBeFalsy()}); +}); +``` + +## Example (tape) ```js import test from 'tape-promise/tape'; @@ -33,7 +56,9 @@ test('GeoJsonLayer#tests', t => { ## Usage -```js +```ts +import {generateLayerTests} from '@deck.gl/test-utils/vitest'; + generateLayerTests({Layer, sampleProps, assert, onError}); ``` diff --git a/docs/api-reference/test-utils/overview.md b/docs/api-reference/test-utils/overview.md index d89ce9a80af..42b8654a2fe 100644 --- a/docs/api-reference/test-utils/overview.md +++ b/docs/api-reference/test-utils/overview.md @@ -20,6 +20,79 @@ yarn add -D @deck.gl/test-utils You typically want the major and minor version of ` @deck.gl/test-utils` to match the version of `@deck.gl/core` that you are using. i.e. you want to use `9.0.x` and `9.0.y` together. Check and if necessary edit your `package.json` to make sure things align. +## Using with Vitest + +`@deck.gl/test-utils` ships a dedicated Vitest entry point at `@deck.gl/test-utils/vitest` that automatically wires up `vi.spyOn()` for layer method spies. This is the recommended way to test deck.gl layers with Vitest. + +### Quick Start + +```bash +npm install --save-dev @deck.gl/test-utils vitest @vitest/browser playwright +``` + +Import from the vitest-specific entry point: + +```ts +import {test, expect} from 'vitest'; +import {testLayer, generateLayerTests} from '@deck.gl/test-utils/vitest'; +``` + +### Setup + +Layer tests require a real WebGL2 context, so tests must run in [Vitest Browser Mode](https://vitest.dev/guide/browser/) with Playwright. JSDOM does not support WebGL and is not a supported environment for `@deck.gl/test-utils`. + +Install browser testing dependencies: + +```bash +npm install --save-dev @vitest/browser playwright +``` + +Configure `vitest.config.ts`: + +```ts +import {defineConfig} from 'vitest/config'; +import {playwright} from '@vitest/browser-playwright'; + +export default defineConfig({ + test: { + browser: { + enabled: true, + provider: playwright({ + launchOptions: { + args: ['--use-angle=swiftshader', '--enable-unsafe-swiftshader'] + } + }), + instances: [{browser: 'chromium'}], + headless: true + } + } +}); +``` + +Write a test: + +```ts +import {test, expect} from 'vitest'; +import {testLayer, generateLayerTests} from '@deck.gl/test-utils/vitest'; +import {ScatterplotLayer} from '@deck.gl/layers'; + +test('ScatterplotLayer', () => { + const testCases = generateLayerTests({ + Layer: ScatterplotLayer, + sampleProps: { + data: [{position: [0, 0]}], + getPosition: d => d.position + }, + assert: (cond, msg) => expect(cond, msg).toBeTruthy() + }); + + testLayer({Layer: ScatterplotLayer, testCases, onError: err => expect(err).toBeFalsy()}); +}); +``` + +See [testLayer](./test-layer.md) for the full API and more examples including custom layer tests. + + ## Layer Conformance Tests Layer conformance tests are designed to verify deck.gl that layers update their internal state correctly in response to various props and prop changes. The layer update test support includes test drivers to initialize a layer and then run a sequence of successive updates, with facilities for validating the layer after each change, and also provides functions to initialize, update and render layers in a test environment. diff --git a/docs/api-reference/test-utils/test-layer.md b/docs/api-reference/test-utils/test-layer.md index ff11cf1aa17..576b6c53fdb 100644 --- a/docs/api-reference/test-utils/test-layer.md +++ b/docs/api-reference/test-utils/test-layer.md @@ -4,7 +4,53 @@ The `testLayer` utility initializes a layer, test layer updates and draw calls o The `testLayerAsync` utility is like `testLayer`, but designed for layers that need to resolve resources asynchronously. -## Example +## Example (Vitest) + +Using the dedicated `@deck.gl/test-utils/vitest` entry point which provides built-in `vi.spyOn()` integration: + +```ts +import {test, expect} from 'vitest'; +import {testLayer} from '@deck.gl/test-utils/vitest'; +import {GeoJsonLayer} from '@deck.gl/layers'; + +test('GeoJsonLayer#tests', () => { + testLayer({ + Layer: GeoJsonLayer, + testCases: [ + // Test case 1 + { + props: {data: []} + }, + // Test case 2 + { + props: { + data: SAMPLE_GEOJSON + }, + onAfterUpdate({layer, oldState, subLayers}) { + expect(layer.state.features).not.toBe(oldState.features); + expect(subLayers.length).toBe(2); + } + }, + // Test case 3 + { + updateProps: { + // will be merged with the previous props + lineWidthScale: 3 + }, + onAfterUpdate({subLayers}) { + const pathLayer = subLayers.find(l => l.id.endsWith('linestrings')); + expect(pathLayer.props.widthScale).toBe(3); + } + } + ], + onError: err => expect(err).toBeFalsy() + }); +}); +``` + +See the [overview](./overview.md#using-with-vitest) for full Vitest setup instructions. + +## Example (tape) Example of layer unit tests using `tape`. The test utility itself is test framework agnostic. @@ -49,7 +95,9 @@ test('GeoJsonLayer#tests', t => { ## Usage -```js +```ts +import {testLayer, testLayerAsync} from '@deck.gl/test-utils/vitest'; + testLayer({Layer, spies, testCases, onError}); await testLayerAsync({Layer, spies, testCases, onError}); ```