fuzzyworld

tower / interior-flight / files / test / raster.test.ts

Branch interior-flight · default branch · all branches

raster.test.ts

2.1 KB · history · blame

1import { readFileSync } from 'node:fs'
2import { describe, expect, it } from 'vitest'
3import {
4 RASTER_HEIGHT, RASTER_MAX_HEIGHT_M, RASTER_MIN_HEIGHT_M, RASTER_WIDTH,
5} from '../src/views/raster.js'
6import { MAP_CUT_WITHOUT_SLATS } from '../src/canon/geometry.js'
7
8const geo = JSON.parse(readFileSync('content/geography.json', 'utf8')) as {
9 render: {
10 gridWidth: number; gridHeight: number
11 minHeightM: number; maxHeightM: number; mapThetaOrigin: number
12 }
13}
14
15/**
16 * The interior view displaces its shell by the height raster and paints it with the
17 * colour raster. Both are read as fractions of numbers the app cannot see, so if
18 * the generator's idea of them ever drifts, the terrain moves or flattens with no
19 * error anywhere.
20 */
21describe('raster metadata matches the generator', () => {
22 it('agrees on the grid', () => {
23 expect(geo.render.gridWidth).toBe(RASTER_WIDTH)
24 expect(geo.render.gridHeight).toBe(RASTER_HEIGHT)
25 })
26
27 it('agrees on what black and white mean in the height map', () => {
28 expect(geo.render.minHeightM).toBe(RASTER_MIN_HEIGHT_M)
29 expect(geo.render.maxHeightM).toBe(RASTER_MAX_HEIGHT_M)
30 })
31
32 /**
33 * The range is declared rather than fitted so the raster keeps its meaning as the
34 * geography is edited. That only works if it actually contains the terrain, so
35 * check it still does — the generator warns, but nobody watches a build log.
36 */
37 it('still covers the terrain it is meant to cover', () => {
38 // The extremes the generator last measured. These are a second line of defence
39 // and a weak one — they are numbers written down when they were true, not the
40 // terrain that came out of the most recent run, so they cannot notice the
41 // geography growing past them. `npm run terrain` now exits non-zero when a
42 // pixel is clamped, which is the check that actually holds.
43 expect(RASTER_MIN_HEIGHT_M).toBeLessThanOrEqual(-521)
44 expect(RASTER_MAX_HEIGHT_M).toBeGreaterThanOrEqual(4381)
45 })
46
47 it('agrees on where the map is cut', () => {
48 expect(geo.render.mapThetaOrigin).toBeCloseTo(MAP_CUT_WITHOUT_SLATS, 6)
49 })
50})