{
  "version": 3,
  "sources": ["../src/vitest.ts", "../src/lifecycle-test.ts", "../src/utils/setup-gl.ts", "../src/utils/layer.ts", "../src/utils/precision.ts", "../src/generate-layer-tests.ts"],
  "sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Vitest-specific entry point with vi.spyOn default\n// Use: import { testLayer } from '@deck.gl/test-utils/vitest'\n\nimport {vi} from 'vitest';\nimport {testLayer as testLayerCore, testLayerAsync as testLayerAsyncCore} from './lifecycle-test';\nimport type {Layer} from '@deck.gl/core';\nimport type {ResetSpy, SpyFactory, TestLayerOptions} from './lifecycle-test';\n\n/** Default spy factory using vi.spyOn */\nconst defaultSpyFactory: SpyFactory = (obj, method) => vi.spyOn(obj, method as never);\n\n/** Default reset for vitest spies - restores original implementation */\nconst defaultResetSpy: ResetSpy = spy => spy.mockRestore?.();\n\nexport function testLayer<LayerT extends Layer>(\n  opts: Omit<TestLayerOptions<LayerT>, 'createSpy' | 'resetSpy'> & {\n    createSpy?: SpyFactory;\n    resetSpy?: ResetSpy;\n  }\n) {\n  const createSpy = opts.createSpy || defaultSpyFactory;\n  const resetSpy = opts.resetSpy || defaultResetSpy;\n  return testLayerCore({...opts, createSpy, resetSpy});\n}\n\nexport function testLayerAsync<LayerT extends Layer>(\n  opts: Omit<TestLayerOptions<LayerT>, 'createSpy' | 'resetSpy'> & {\n    createSpy?: SpyFactory;\n    resetSpy?: ResetSpy;\n  }\n) {\n  const createSpy = opts.createSpy || defaultSpyFactory;\n  const resetSpy = opts.resetSpy || defaultResetSpy;\n  return testLayerAsyncCore({...opts, createSpy, resetSpy});\n}\n\n// Re-export non-spy utilities\nexport {testInitializeLayer, testInitializeLayerAsync} from './lifecycle-test';\nexport {getLayerUniforms} from './utils/layer';\nexport {toLowPrecision} from './utils/precision';\nexport {gl, device} from './utils/setup-gl';\nexport {generateLayerTests} from './generate-layer-tests';\n\n// Types\nexport type {LayerTestCase, ResetSpy, SpyFactory, TestLayerOptions} from './lifecycle-test';\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 {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\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 {_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"],
  "mappings": "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",
  "names": ["testLayer", "testLayerAsync", "import_core", "count", "_a", "testLayer", "testLayerAsync"]
}
