tower / files / test / photos.test.ts
photos.test.ts
| 1 | import { readFileSync } from 'node:fs' |
| 2 | import { describe, expect, it } from 'vitest' |
| 3 | import { parsePhoto, photoId } from '../src/world/photos.js' |
| 4 | |
| 5 | const interior = { |
| 6 | id: 'far-cap', view: 'interior', hours: 13, dial: 'temperate', aspect: 1.5, |
| 7 | theta: 0, z: 270_000, eyeM: 1.7, yaw: 0, pitch: 0.2, fovDeg: 60, spin: 0, |
| 8 | } |
| 9 | const exterior = { |
| 10 | id: 'outside', view: 'exterior', hours: 30.5, dial: 'full', aspect: 1.47, hull: 'rock', |
| 11 | position: [160, -360, 780], target: [0, 0, 510], phase: 1.2, fovDeg: 42, |
| 12 | } |
| 13 | |
| 14 | describe('photographs (D-099)', () => { |
| 15 | it('reads a shot of either view back as it was written', () => { |
| 16 | expect(parsePhoto(interior)).toEqual(interior) |
| 17 | expect(parsePhoto(exterior)).toEqual(exterior) |
| 18 | expect(parsePhoto({ ...interior, note: 'the sun just out' }).note).toBe('the sun just out') |
| 19 | }) |
| 20 | |
| 21 | it('says what is wrong with an entry typed by hand', () => { |
| 22 | expect(() => parsePhoto({ ...interior, pitch: 2 })).toThrow('far-cap: pitch') |
| 23 | expect(() => parsePhoto({ ...interior, z: -1 })).toThrow('far-cap: z') |
| 24 | expect(() => parsePhoto({ ...interior, dial: 'bright' })).toThrow('dial') |
| 25 | expect(() => parsePhoto({ ...exterior, hull: 'glass' })).toThrow('hull') |
| 26 | expect(() => parsePhoto({ ...exterior, target: [0, 0] })).toThrow('target') |
| 27 | expect(() => parsePhoto({ ...interior, view: 'map' })).toThrow('view') |
| 28 | expect(() => parsePhoto({ ...interior, aspect: 0 })).toThrow('aspect') |
| 29 | }) |
| 30 | |
| 31 | it('keeps an id fit to be a file name', () => { |
| 32 | expect(photoId(' Far cap, from the Capital! ')).toBe('far-cap-from-the-capital') |
| 33 | expect(photoId('***')).toBe('') |
| 34 | for (const id of ['../world', 'a/b', 'Far Cap', '', 'a--b']) { |
| 35 | expect(() => parsePhoto({ ...interior, id })).toThrow('id') |
| 36 | } |
| 37 | }) |
| 38 | |
| 39 | it('has a list every entry of which can be rendered, under names that do not collide', () => { |
| 40 | const list = JSON.parse(readFileSync('content/photos.json', 'utf8')) as unknown[] |
| 41 | const ids = list.map((p) => parsePhoto(p).id) |
| 42 | expect(new Set(ids).size).toBe(ids.length) |
| 43 | }) |
| 44 | }) |