import test from 'node:test' import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import ts from 'typescript' const vue = readFileSync(new URL('../pages/index.vue', import.meta.url), 'utf8') const script = vue.split('')[0] const tree = ts.createSourceFile('index.ts', script, ts.ScriptTarget.Latest, true) function action(name, scope) { const node = tree.statements.find(n => ts.isFunctionDeclaration(n) && n.name?.text === name) assert.ok(node, `${name} exists`) const code = ts.transpileModule(node.getText(tree), { compilerOptions: { target: ts.ScriptTarget.ES2022 } }).outputText return new Function(...Object.keys(scope), `${code}; return ${name}`)(...Object.values(scope)) } function fixture() { const current = { id: 'displayed', settings: { steps: 24 } } const state = { input: 'existing input', reference: 'existing reference', prompt: 'current prompt', steps: 19, engine: 'flux', mode: 'generate' } const calls = [] return { state, calls, current, scope: { editResultUrl: { value: '/api/library/stills/displayed' }, lastV2StillId: { value: 'older-generation' }, editDownloadName: { value: 'displayed' }, stillIdFromLibraryUrl: () => 'displayed', stills: { value: [current, { id: 'older-generation' }] }, usingReferenceBusy: { value: false }, usingInputSettingsBusy: { value: false }, $fetch: async () => new Blob(['pixels'], { type: 'image/png' }), File, readFile: (file, options) => { state.input = file; calls.push(options) }, setEditRef: file => { state.reference = file }, useStillAsInput: async still => { calls.push(still.id) }, loadLibrary: async () => {}, scrollToStudioInput: () => {}, toast: () => {}, selectStudioKind: () => { throw new Error('Must not change workspace') }, setV2Engine: () => { throw new Error('Must not change engine') }, resetImage: () => { throw new Error('Must not clear input') } } } } test('input-still action loads only pixels and preserves current settings', async () => { const f = fixture() await action('useEditAsInput', f.scope)() assert.ok(f.state.input instanceof File) assert.deepEqual(f.calls, [{ stillId: 'displayed', keepThumbnailPref: true }]) assert.equal(f.state.prompt, 'current prompt'); assert.equal(f.state.steps, 19) assert.equal(f.state.reference, 'existing reference') }) test('reference action changes only the reference, preserving input, prompt, engine and mode', async () => { const f = fixture() await action('useOutputAsFluxReference', f.scope)() assert.ok(f.state.reference instanceof File) assert.deepEqual({ ...f.state, reference: null }, { input: 'existing input', reference: null, prompt: 'current prompt', steps: 19, engine: 'flux', mode: 'generate' }) }) test('full input action restores the displayed image settings instead of the previous generation', async () => { const f = fixture() await action('useOutputWithSettings', f.scope)() assert.deepEqual(f.calls, ['displayed']) })