import assert from 'node:assert/strict'; import { fileURLToPath } from 'node:url'; import vue from '@vitejs/plugin-vue'; import { createServer } from 'vite'; import { createSSRApp, h } from 'vue'; import { renderToString } from 'vue/server-renderer'; const server = await createServer({ configFile: false, cacheDir: 'node_modules/.vite/acceptance-criteria-fixture', plugins: [vue()], resolve: { alias: { '@': fileURLToPath(new URL('../../resources/js', import.meta.url)), }, }, server: { middlewareMode: true, hmr: false, watch: null }, }); try { const { canIndentAcceptanceCriterion: canIndent, indentAcceptanceCriterion: indent, removeAcceptanceCriterion: remove, syncAcceptanceCriteriaDescendantCheckedState: toggle, normalizeAcceptanceCriteria: normalize, } = await server.ssrLoadModule('/resources/js/lib/acceptance-criteria.ts'); const items = [ { id: 11, text: 'Parent', indent: 0, checked: false }, { id: 12, text: 'Child', indent: 1, checked: true }, { id: 13, text: 'Grandchild', indent: 2, checked: false }, { id: 14, text: 'Next', indent: 0, checked: false }, ]; const original = structuredClone(items); assert.equal(canIndent(items, 0), false); assert.equal(canIndent(items, 1), false); assert.equal(canIndent(items, 3), true); assert.deepEqual( indent(items, 1, -1).map((item) => item.indent), [0, 0, 1, 0], ); assert.deepEqual(indent(indent(items, 1, -1), 1, 1), items); assert.deepEqual(indent(items, 0, -1), items); assert.deepEqual(indent(items, -1, 1), items); assert.deepEqual(remove(items, 0), [ { ...items[1], indent: 0 }, { ...items[2], indent: 1 }, items[3], ]); assert.deepEqual(remove(items, 1), [ items[0], { ...items[2], indent: 1 }, items[3], ]); assert.deepEqual(remove(items, 99), items); assert.deepEqual( toggle(items, 0, true).map((item) => item.checked), [true, true, true, false], ); assert.deepEqual( toggle(items, 1, false).map((item) => item.checked), [false, false, false, false], ); const deep = Array.from({ length: 9 }, (_, indent) => ({ text: 'Deep', checked: false, indent, })); assert.equal( canIndent([{ text: 'Before', indent: 0, checked: false }, ...deep], 1), false, ); assert.deepEqual( normalize(remove(items, 0)).map((item) => item.id), [12, 13, 14], ); assert.deepEqual(items, original, 'Editing must not mutate saved criteria'); const { default: Checklist } = await server.ssrLoadModule( '/resources/js/components/tickets/AcceptanceCriteriaChecklist.vue', ); const { createLocalization } = await server.ssrLoadModule( '/resources/js/lib/localization.ts', ); const render = (props) => renderToString( createSSRApp({ render: () => h(Checklist, props) }).use( createLocalization(), ), ); const editable = await render({ modelValue: items }); assert.equal((editable.match(/