77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|||
|
|
import {
|
||
|
|
assertSameCellsShape,
|
||
|
|
getBoundaryCondition,
|
||
|
|
getCaClassFromParams,
|
||
|
|
numericGridSize,
|
||
|
|
resolveBoundaryIndex,
|
||
|
|
supportsCaClass
|
||
|
|
} from '../admin/src/caRuntime.js'
|
||
|
|
import type { Cells } from '../admin/src/types.js'
|
||
|
|
|
||
|
|
describe('CA runtime helpers', () => {
|
||
|
|
it('extracts CA class metadata from resolved scene params', () => {
|
||
|
|
expect(
|
||
|
|
getCaClassFromParams({
|
||
|
|
caClass: { dimensions: 2, states: 2, neighborhoodId: 'moore' }
|
||
|
|
})
|
||
|
|
).toEqual({ dimensions: 2, states: 2, neighborhoodId: 'moore' })
|
||
|
|
})
|
||
|
|
|
||
|
|
it('matches runtimes by dimensions and states without requiring neighbourhood', () => {
|
||
|
|
expect(
|
||
|
|
supportsCaClass(
|
||
|
|
{ supported_classes: [{ dimensions: 2, states: 2 }] },
|
||
|
|
{ dimensions: 2, states: 2, neighborhoodId: 'von-neumann' }
|
||
|
|
)
|
||
|
|
).toBe(true)
|
||
|
|
expect(
|
||
|
|
supportsCaClass(
|
||
|
|
{ supported_classes: [{ dimensions: 3, states: 2 }] },
|
||
|
|
{ dimensions: 2, states: 2 }
|
||
|
|
)
|
||
|
|
).toBe(false)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('honors engine neighbourhood metadata when supplied', () => {
|
||
|
|
expect(
|
||
|
|
supportsCaClass(
|
||
|
|
{ supported_classes: [{ dimensions: 2, states: 2, neighborhoodId: 'moore' }] },
|
||
|
|
{ dimensions: 2, states: 2, neighborhoodId: 'moore' }
|
||
|
|
)
|
||
|
|
).toBe(true)
|
||
|
|
expect(
|
||
|
|
supportsCaClass(
|
||
|
|
{ supported_classes: [{ dimensions: 2, states: 2, neighborhoodId: 'moore' }] },
|
||
|
|
{ dimensions: 2, states: 2, neighborhoodId: 'von-neumann' }
|
||
|
|
)
|
||
|
|
).toBe(false)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('defaults boundary handling to wrap and keeps legacy wrap=false as fixed', () => {
|
||
|
|
expect(getBoundaryCondition({ simulation: { grid: {} } })).toBe('wrap')
|
||
|
|
expect(getBoundaryCondition({ simulation: { grid: { wrap: false } } })).toBe('fixed')
|
||
|
|
expect(getBoundaryCondition({ simulation: { grid: { boundary: 'mirror' } } })).toBe('mirror')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('resolves wrap, mirror, and fixed boundary indexes', () => {
|
||
|
|
expect(resolveBoundaryIndex(-1, 5, 'wrap')).toBe(4)
|
||
|
|
expect(resolveBoundaryIndex(-1, 5, 'mirror')).toBe(1)
|
||
|
|
expect(resolveBoundaryIndex(-1, 5, 'fixed')).toBeNull()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('resolves grid sizes for 2D and 3D classes', () => {
|
||
|
|
expect(numericGridSize({ size: [7, 8, 9] }, 2)).toEqual([7, 8, 1])
|
||
|
|
expect(numericGridSize({ size: [7, 8, 9] }, 3)).toEqual([7, 8, 9])
|
||
|
|
})
|
||
|
|
|
||
|
|
it('rejects invalid engine output shapes', () => {
|
||
|
|
const input: Cells = [
|
||
|
|
[false, true],
|
||
|
|
[true, false]
|
||
|
|
]
|
||
|
|
expect(() => assertSameCellsShape(input, [[true]], 'test output')).toThrow('preserve the input grid dimensions')
|
||
|
|
expect(() => assertSameCellsShape(input, [[true], [false, true]], 'test output')).toThrow('rectangular')
|
||
|
|
})
|
||
|
|
})
|