mirror of
https://github.com/zoo-apps/zoolabs.io.git
synced 2026-10-30 14:56:27 +00:00
The stamps put `?v=<hash>` on a clip URL. This test builds a path by putting `public` in front of that URL, so since the stamps landed it has been asking the filesystem for `public/bg_video/emotion/Admiration.mp4?v=b8c659df` — a check that can only fail. Nothing said so, because the runner it asked for was not answering and the run sat in the queue until GitHub cancelled it. It also only asked whether the file EXISTS. An LFS pointer exists: it is 132 bytes of text, named correctly, and it plays nothing — which is how these clips reached the edge once already and stayed there. Size is the question, so size is what it asks.
88 lines
3.4 KiB
TypeScript
88 lines
3.4 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import { existsSync, readdirSync, statSync } from 'node:fs'
|
|
import { test } from 'node:test'
|
|
import { clipFor, FEELINGS, read, RESTING, visible } from './companion.ts'
|
|
|
|
// A clip's URL carries a stamp (`?v=<hash>`); a clip's FILE does not. The two
|
|
// were the same string before the stamps landed, and this dropped the query the
|
|
// moment they differed — checking `public/…/Admiration.mp4?v=b8c659df` on disk
|
|
// is a check that can only fail.
|
|
const asset = (url: string) => `public${url.split('?')[0]}`
|
|
|
|
// An LFS pointer is a 132-byte text file that exists, is named right, and plays
|
|
// nothing. These clips reached the edge as pointers once already, so presence is
|
|
// not the question — size is.
|
|
const POINTER = 1024
|
|
|
|
test('every feeling Blue can show has a clip on disk', () => {
|
|
for (const feeling of FEELINGS) {
|
|
const file = asset(clipFor(feeling))
|
|
assert.ok(existsSync(file), `missing clip for ${feeling}`)
|
|
assert.ok(statSync(file).size > POINTER, `${feeling} is an LFS pointer, not a clip`)
|
|
}
|
|
})
|
|
|
|
test('every clip on disk is a feeling Blue can show', () => {
|
|
const onDisk = readdirSync('public/bg_video/emotion')
|
|
.filter((f) => f.endsWith('.mp4'))
|
|
.map((f) => f.replace('.mp4', ''))
|
|
assert.deepEqual([...onDisk].sort(), [...FEELINGS].sort())
|
|
})
|
|
|
|
test('resting clips exist', () => {
|
|
for (const url of RESTING) {
|
|
const file = asset(url)
|
|
assert.ok(existsSync(file), `missing ${url}`)
|
|
assert.ok(statSync(file).size > POINTER, `${url} is an LFS pointer, not a clip`)
|
|
}
|
|
})
|
|
|
|
test('reads the feeling off a reply and keeps the prose', () => {
|
|
const { text, feeling } = read('Calves are born grey.\n\n[feeling: Interest]')
|
|
assert.equal(text, 'Calves are born grey.')
|
|
assert.equal(feeling, 'Interest')
|
|
})
|
|
|
|
test('a reply with no tag leaves the feeling alone', () => {
|
|
assert.deepEqual(read('Just prose.'), { text: 'Just prose.', feeling: null })
|
|
})
|
|
|
|
test('an unknown feeling is refused rather than shown', () => {
|
|
assert.equal(read('Hi.\n[feeling: Hungry]').feeling, null)
|
|
})
|
|
|
|
test('a half-arrived tag stays hidden while streaming', () => {
|
|
assert.equal(visible('Sound moves faster in water.\n\n[feeli'), 'Sound moves faster in water.')
|
|
assert.equal(visible('Sound moves faster in water.'), 'Sound moves faster in water.')
|
|
})
|
|
|
|
test('what gets read aloud drops the scaffolding, not the sentence', async () => {
|
|
const { sayable } = await import('./voice.ts')
|
|
assert.equal(sayable('**Calves** are grey.'), 'Calves are grey.')
|
|
assert.equal(sayable('See https://zoo.ngo for more.'), 'See for more.')
|
|
assert.equal(sayable('Try this:\n```js\nconst a = 1\n```\nDone.'), 'Try this: Done.')
|
|
assert.equal(sayable(' '), '')
|
|
})
|
|
|
|
// A 3B model writes the tag its own way. The feeling still lands, and the
|
|
// bracket never survives into what a child reads.
|
|
test('a tag the model spelled its own way still lands', () => {
|
|
assert.deepEqual(read('Calves start grey.\n[Calmness: Blue]'), {
|
|
text: 'Calves start grey.',
|
|
feeling: 'Calmness',
|
|
})
|
|
assert.deepEqual(read('Sound carries.\n[Interest]'), {
|
|
text: 'Sound carries.',
|
|
feeling: 'Interest',
|
|
})
|
|
assert.deepEqual(read('Ice is thinning.\n[ feeling = Sadness ]'), {
|
|
text: 'Ice is thinning.',
|
|
feeling: 'Sadness',
|
|
})
|
|
})
|
|
|
|
test('a bracket that is the reply own prose is left alone', () => {
|
|
const cite = 'Belugas use echolocation [see the 2019 survey]'
|
|
assert.deepEqual(read(cite), { text: cite, feeling: null })
|
|
})
|