clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

main
miau-is-true / tests / share.test.js
share.test.js 5.0K
1import test from 'node:test';2import assert from 'node:assert/strict';3import { decodeSharedPack, encodeSharedPack, exportCommonJS } from '../src/share.js';4import { loadMod } from '../src/mods.js';56const pack = {7 manifest: { id: 'emoji-garden', name: 'Emoji Garden', version: '1.0.0' },8 palette: { miau: '🐈', flag: '🚩' },9 levels: [{ id: 'first-garden', title: 'First garden', width: 4, height: 2, objects: [10 { kind: 'word', text: 'miau', x: 0, y: 0 },11 { kind: 'word', text: 'IS', x: 1, y: 0 },12 { kind: 'word', text: 'you', x: 2, y: 0 },13 { kind: 'object', noun: 'miau', x: 0, y: 1 },14 ] }],15};1617test('shared packs round trip as normalized Unicode data', () => {18 const payload = encodeSharedPack(pack);19 assert.match(payload, /^miau1\.[A-Za-z0-9_-]+\.[0-9a-f]{8}$/);20 const decoded = decodeSharedPack(payload);21 assert.equal(decoded.manifest.engine, 1);22 assert.equal(decoded.manifest.rules, 1);23 assert.equal(decoded.levels[0].objects[0].text, 'MIAU');24 assert.equal(decoded.levels[0].objects[3].noun, 'MIAU');25 assert.equal(decoded.palette.MIAU, '🐈');26});2728test('shared packs preserve bounded directional palette faces', () => {29 const directional = { ...pack, palette: { ...pack.palette, MIAU: { glyph: '🐈', faces: 'right' } } };30 const decoded = decodeSharedPack(encodeSharedPack(directional));31 assert.deepEqual(decoded.palette.MIAU, { glyph: '🐈', faces: 'right' });32 assert.equal(decoded.palette.FLAG, '🚩');33});3435test('shared data preserves authored world identity for service fallback', () => {36 const authored = {37 ...pack,38 manifest: { ...pack.manifest, world: { glyph: '⚙️', tagline: 'A clockwork world.', accent: 'tick' } },39 };40 const decoded = decodeSharedPack(encodeSharedPack(authored));41 assert.deepEqual(decoded.manifest.world, authored.manifest.world);42});4344test('shared data preserves invalid authored world fields for preview diagnostics', () => {45 const authored = {46 ...pack,47 manifest: { ...pack.manifest, world: { glyph: '🐈🐈', accent: 'glow' } },48 };49 const decoded = decodeSharedPack(encodeSharedPack(authored));50 assert.deepEqual(decoded.manifest.world, authored.manifest.world);51});5253test('shared packs preserve normalized declarative automata', () => {54 const automata = {55 ...pack,56 levels: [{ ...pack.levels[0], automata: [{57 id: 'cat-patrol', property: 'move', phase: 0,58 pattern: [{ action: 'move', dx: 1, dy: 0, cue: 'step', sound: 'move' }, { action: 'wait' }],59 }] }],60 };61 const decoded = decodeSharedPack(encodeSharedPack(automata));62 assert.deepEqual(decoded.levels[0].automata, [{63 id: 'cat-patrol', property: 'MOVE', phase: 0,64 pattern: [{ action: 'move', dx: 1, dy: 0, cue: 'step', sound: 'move' }, { action: 'wait' }],65 }]);66});6768test('encoding is stable and CommonJS export is deterministic data only', () => {69 const first = encodeSharedPack(pack);70 const second = encodeSharedPack({ levels: pack.levels, palette: pack.palette, manifest: pack.manifest });71 assert.equal(first, second);72 const source = exportCommonJS(pack);73 assert.equal(source, exportCommonJS(pack));74 assert.match(source, /^'use strict';\n\nmodule\.exports = /);75 assert.doesNotMatch(source, /require\(|function\s*\(/);76 assert.match(source, /🐈/u);77});7879test('CommonJS export round trips through the trusted loader with authored IDs', () => {80 const loaded = loadMod(exportCommonJS(pack));81 assert.equal(loaded.manifest.id, 'emoji-garden');82 assert.equal(loaded.manifest.rules, 1);83 assert.equal(loaded.levels[0].id, 'first-garden');84 assert.equal(loaded.levels[0].objects[0].text, 'MIAU');85 assert.equal('rules' in loaded.levels[0], false);86 assert.equal('moves' in loaded.levels[0], false);87});8889test('rejects tampered, malformed, wrong-schema, and oversized payloads', () => {90 const payload = encodeSharedPack(pack);91 const changed = `${payload.slice(0, -9)}${payload.endsWith('0') ? '1' : '0'}${payload.slice(-8)}`;92 assert.throws(() => decodeSharedPack(changed), /integrity|malformed/);93 assert.throws(() => decodeSharedPack('miau1.not-json.deadbeef'), /integrity|malformed/);94 assert.throws(() => decodeSharedPack('miau1.a$bc.deadbeef'), /encoding|malformed/);95 // _w decodes to the invalid UTF-8 byte 0xff; fatal decoding must reject it.96 assert.throws(() => decodeSharedPack('miau1._w.deadbeef'), /encoding|UTF-8|malformed/);97 assert.throws(() => decodeSharedPack('miau2.abc.deadbeef'), /schema/);98 const vocabulary = Array.from({ length: 10000 }, (_, index) => `TOKEN${index}`);99 assert.throws(() => encodeSharedPack({ ...pack, vocabulary }), /exceeds/);100});101102test('decoder validates decoded data without executing source', () => {103 const malicious = {104 manifest: pack.manifest,105 levels: [{ id: 'safe-level', width: 2, height: 1, objects: [{ kind: 'word', text: 'MIAU', x: 0, y: 0 }] }],106 };107 const decoded = decodeSharedPack(encodeSharedPack(malicious));108 assert.equal(decoded.levels[0].objects[0].text, 'MIAU');109 assert.equal(Object.prototype.hasOwnProperty.call(decoded, 'exports'), false);110});