// Run: node tests/place-navigation.mjs import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { runInNewContext } from 'node:vm' import ts from 'typescript' const source = readFileSync(new URL('../src/components/ScenariosEditorPage.vue', import.meta.url), 'utf8') const handler = source.match(/function navigateToPlace\([^]*?\n}/)[0] const places = [ { oldCode: 'A', code: 'renamed', mode: 'edit', text: 'Unsaved' }, { code: 'B', mode: 'show-editor', hidden: true }, { code: 'quote"#[]', mode: 'show-editor' }, ] const calls = [] const errors = [] const state = { editorPlaces: { value: places }, scrollContainer: { value: { scrollTop: 120, getBoundingClientRect: () => ({ top: 70 }), scrollTo: (options) => calls.push(['scroll', options.top]), } }, placeCards: new Map(places.map((place) => [place, { focus: () => calls.push(['focus', place.code]), getBoundingClientRect: () => ({ top: 460 }), }])), message: { error: (text) => errors.push(text) }, } runInNewContext(ts.transpile(handler, { target: ts.ScriptTarget.ES2022 }), state) const before = JSON.stringify(places) for (const code of ['B', 'A', 'A', 'quote"#[]']) { state.navigateToPlace(code) } assert.deepEqual(calls, ['B', 'renamed', 'renamed', 'quote"#[]'].flatMap((code) => [ ['focus', code], ['scroll', 500], ])) for (const code of ['', undefined, 'missing', 'renamed']) state.navigateToPlace(code) assert.equal(errors.length, 4) assert.equal(calls.length, 8) assert.equal(JSON.stringify(places), before) console.log('Place navigation: targets, missing codes, rename, focus and unsaved data passed')