Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586// src/plugin/__tests__/editor-suggest-mode-toggle.test.ts/** * Regression test for plan decision #1: the dispatcher MUST be a top-level * extension, NOT inside livePreviewCompartment. Reconfiguring the live * preview compartment must NOT tear down the dispatcher's AbortController * or its dropdown DOM. */import { describe, it, expect, afterEach } from 'vitest'import { EditorSuggest } from '../editor-suggest'import { getDispatcherController } from '../../editor/extensions/editor-suggest-dispatcher'import { livePreview } from '../../editor/extensions/live-preview'import { mountCM6EditorWithSourceMode, typeText, findDropdown, type MountedHarness,} from './editor-suggest-test-harness'
class BracketSuggest extends EditorSuggest<string> { onTrigger(cursor: { line: number; ch: number }, editor: { getLine(line: number): string }) { const line = editor.getLine(cursor.line) const before = line.slice(0, cursor.ch) const m = /\[\[([^\]\[]*)$/.exec(before) if (!m) return null return { start: { line: cursor.line, ch: m.index }, end: { line: cursor.line, ch: cursor.ch }, query: m[1], } } async getSuggestions() { return ['a', 'b'] } renderSuggestion(item: string, el: HTMLElement) { el.textContent = item } selectSuggestion() {}}
let harness: MountedHarness | null = null
afterEach(() => { harness?.destroy() harness = null document.body.innerHTML = ''})
async function flush(): Promise<void> { await new Promise((r) => setTimeout(r, 80))}
describe('mode-toggle regression (decision #1)', () => { it('survives source ↔ live-preview compartment reconfigure (dispatcher persists)', async () => { const h = await mountCM6EditorWithSourceMode() harness = h const sug = new BracketSuggest(h.app) h.app.workspace.registerEditorSuggest(sug) typeText(h.view, '[[') await flush() expect(findDropdown()).not.toBeNull() const dropdownBefore = findDropdown() // Dropdown active means controller is non-null AND not aborted. const ctrlBefore = getDispatcherController(h.view, h.app) expect(ctrlBefore).not.toBeNull()
// Reconfigure the livePreview compartment to enable live-preview // decorations. The dispatcher (top-level) must survive this without // re-creating its state. h.view.dispatch({ effects: h.livePreviewCompartment.reconfigure( livePreview({ wikilink: { onNavigate: () => {}, resolveLink: () => true }, }), ), }) await flush() // Dropdown DOM still in the document. const dropdownAfter = findDropdown() expect(dropdownAfter).not.toBeNull() expect(dropdownAfter).toBe(dropdownBefore) // Same AbortController instance — dispatcher was NOT re-created. const ctrlAfter = getDispatcherController(h.view, h.app) expect(ctrlAfter).toBe(ctrlBefore) })})