Spaces:
Running
Running
Download tests/layout.test.mjs from alphabell/MOSS-Layout-Studio: direct link, hf CLI and curl.
- Browser
- Download file 6.21 kB
-
https://huggingface.co/spaces/alphabell/MOSS-Layout-Studio/resolve/main/tests/layout.test.mjs
- Command line
-
hf download hf://spaces/alphabell/MOSS-Layout-Studio/tests/layout.test.mjs
-
curl -L -o layout.test.mjs https://huggingface.co/spaces/alphabell/MOSS-Layout-Studio/resolve/main/tests/layout.test.mjs
6.21 kB
| import test from 'node:test'; | |
| import assert from 'node:assert/strict'; | |
| import { compileDraft, makeDraft, makeLayout, parseLayout, parseStrictJSON, toCentralBox, fromCentralBox, resizeLayout, validateDraft, clampRect } from '../layout.mjs'; | |
| const draft = () => ({ width: 1536, height: 1024, bbox_coord_space: 'abs', bbox_format: 'xyxy', summary: { caption: 'A ceramic campaign.', meta: ['poster'], canvas: 'single', palette: ['ivory'] }, items: [{ label: 'text', caption: 'Dark-green lettering.', text: '把日常,过成诗。\n"MOSS" 🪴', bbox: [928, 272, 1408, 448], tags: ['title'], palette: ['green'] }] }); | |
| test('official landscape example converts to centered yxyx without content loss or mutation', () => { | |
| const source = draft(), before = structuredClone(source), out = compileDraft(source); | |
| assert.deepEqual(out.items[0].bbox, [-240, 160, -64, 640]); | |
| assert.deepEqual(out.summary, source.summary); assert.equal(out.items[0].text, source.items[0].text); | |
| assert.deepEqual(out.items[0].tags, ['title']); assert.deepEqual(out.items[0].palette, ['green']); | |
| assert.equal(out.bbox_coord_space, 'abs_centralized'); assert.equal(out.bbox_format, 'yxyx'); | |
| assert.equal('width' in out, false); assert.equal('height' in out, false); assert.deepEqual(source, before); | |
| }); | |
| test('portrait, fractions and compiler precision enclose before center subtraction', () => { | |
| assert.deepEqual(toCentralBox([0, 0, 768, 1344], 768, 1344), [-672, -384, 672, 384]); | |
| assert.deepEqual(toCentralBox([10.9, 20.1, 100.01, 200.99], 768, 1344), [-652, -374, -471, -283]); | |
| assert.deepEqual(toCentralBox([1.00000000001, 2, 100, 200], 768, 1344), [-670, -383, -472, -284]); | |
| assert.deepEqual(toCentralBox([0, 0, 99.99999999999, 199.99999999999], 768, 1344), [-672, -384, -472, -284]); | |
| }); | |
| test('draft and compiled round trips retain optional creative fields and literal Unicode', () => { | |
| const source = draft(), state = parseLayout(JSON.stringify(source)); | |
| assert.deepEqual(makeDraft(state), source); | |
| assert.deepEqual(makeLayout(parseLayout(JSON.stringify(compileDraft(source)), { width: 1536, height: 1024 })), compileDraft(source)); | |
| assert.equal('id' in makeDraft(state).items[0], false); | |
| assert.equal(state.items[0].text, source.items[0].text); | |
| }); | |
| test('compiled import requires dimensions and honors non-square axis order', () => { | |
| const source = compileDraft(draft()); assert.throws(() => parseLayout(JSON.stringify(source)), /width/); | |
| const r = fromCentralBox([-288, -592, 352, 32], 1536, 1024); | |
| assert.deepEqual(r, { x: 176, y: 224, w: 624, h: 640 }); | |
| }); | |
| test('invalid numeric geometry, zero area and out-of-canvas boxes are rejected', () => { | |
| for (const box of [[-1,0,100,100], [0,0,1537,100], [100,0,50,100], [0,0,0,100], [0,0,100], [true,0,100,100], [0,0,NaN,100], [0,0,Infinity,100], [1,0,1.00000000001,100]]) { | |
| const source = draft(); source.items[0].bbox = box; assert.throws(() => compileDraft(source)); | |
| } | |
| const source = draft(); source.width = 1535; assert.equal(validateDraft(source).valid, false); | |
| }); | |
| test('unknown fields, nested layouts and blank content cannot be silently lost', () => { | |
| const modifications = [s=>s.other='unknown', s=>s.items[0].children=[], s=>s.items[0].id='editor-id', s=>s.summary.meta=[''], s=>s.summary.caption=' ', s=>s.items[0].text='', s=>s.items=[], s=>s.items[0].label='face', s=>s.summary.canvas='other']; | |
| for (const modify of modifications) { const source = draft(); modify(source); assert.throws(() => compileDraft(source)); } | |
| const source = draft(); delete source.items[0].text; assert.throws(() => compileDraft(source), /literal text/); | |
| }); | |
| test('strict import rejects duplicate keys including escaped keys and invalid JSON constants', () => { | |
| for (const value of ['{"x":1,"x":2}', '{"x":1,"\\u0078":2}', '{"a":{"x":1,"x":2}}', '[NaN]', '{"x":Infinity}', '{"x":1e400}', '{"x":01}', '{"x":1,}', 'null trailing', '"unterminated']) assert.throws(() => parseStrictJSON(value)); | |
| assert.deepEqual(parseStrictJSON('{"__proto__":{"polluted":true}}'), JSON.parse('{"__proto__":{"polluted":true}}')); | |
| assert.equal({}.polluted, undefined); | |
| }); | |
| test('width and height retain JSON integer-literal semantics', () => { | |
| const source = JSON.stringify(draft()); | |
| assert.throws(() => parseLayout(source.replace('"width":1536', '"width":1536.0')), /integer JSON literal/); | |
| assert.throws(() => parseLayout(source.replace('"height":1024', '"height":1.024e3')), /integer JSON literal/); | |
| assert.equal(parseLayout(source).width, 1536); | |
| }); | |
| test('resolution recommendations produce warnings and are separate from accepted schema', () => { | |
| const source = draft(); source.width = source.height = 8192; | |
| const result = validateDraft(source); assert.equal(result.valid, true); assert.equal(result.warnings.length, 1); | |
| }); | |
| test('text validation follows Python Unicode whitespace without normalization', () => { | |
| for (const space of ['\u0085', '\u001c', '\u2007', '\u3000']) { | |
| const source = draft(); source.summary.caption = space; assert.equal(validateDraft(source).valid, false); | |
| } | |
| const source = draft(); source.summary.caption = '\ufeff'; | |
| assert.equal(compileDraft(source).summary.caption, '\ufeff'); | |
| }); | |
| test('overlap remains permitted and exact text, tags and arrays retain order', () => { | |
| const source = draft(); source.items.push({ ...structuredClone(source.items[0]), text: 'Second\nline' }); | |
| assert.deepEqual(compileDraft(source).items.map(x=>x.bbox), [[-240,160,-64,640],[-240,160,-64,640]]); | |
| assert.deepEqual(makeDraft(parseLayout(JSON.stringify(source))), source); | |
| }); | |
| test('explicit scaling versus local clamp policy preserves inputs and enforces edit bounds', () => { | |
| const state = parseLayout(JSON.stringify(draft())), before = structuredClone(state); | |
| const half = resizeLayout(state, 768, 512); | |
| assert.equal(half.items[0].x, state.items[0].x/2); assert.equal(half.items[0].h, state.items[0].h/2); | |
| const clamped = resizeLayout(state, 768, 512, { scale:false }); | |
| assert.equal(clamped.items[0].x+clamped.items[0].w,768); assert.equal(clamped.items[0].y+clamped.items[0].h,448); | |
| assert.deepEqual(state,before); assert.deepEqual(clampRect({x:-9,y:999,w:50,h:50},1024,1024), {x:0,y:974,w:50,h:50}); | |
| }); | |