Files
sori.studio/tests/useAdminMarkdownEditorFocusActions.test.js

144 lines
4.5 KiB
JavaScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { nextTick, ref } from 'vue'
import { useAdminMarkdownEditorFocusActions } from '../composables/useAdminMarkdownEditorFocusActions.js'
/**
* 테스트용 에디터 포커스 액션 상태를 만든다.
* @param {Object} [options] - 테스트 옵션
* @returns {Object} 테스트 상태
*/
const createEditorFocusActionsState = (options = {}) => {
const activeMode = ref(options.activeMode ?? 'write')
const value = ref(options.value ?? '첫 줄\n둘째 줄')
const activeLogicalLineIndex = ref(options.activeLogicalLineIndex ?? 0)
const calls = {
focusPreview: [],
focusTextareaAtLine: [],
refreshCaret: 0,
scrollPreviewToTop: 0,
setTextareaSelection: []
}
const textarea = options.textarea ?? {
focused: false,
scrollTop: 48,
selection: null,
focus() {
this.focused = true
},
setSelectionRange(start, end) {
this.selection = { start, end }
}
}
const actions = useAdminMarkdownEditorFocusActions({
activeMode,
value,
activeLogicalLineIndex,
getWriteTextareaElement: () => textarea,
getLineIndexAtOffset: (offset) => String(value.value).slice(0, offset).split('\n').length - 1,
getLineStartOffset: (lineIndex) => {
const lines = String(value.value).split('\n')
return lines.slice(0, lineIndex).join('\n').length + (lineIndex > 0 ? 1 : 0)
},
setTextareaSelection: (start, end, selectionOptions) => {
calls.setTextareaSelection.push({ start, end, options: selectionOptions })
},
focusTextareaAtLine: (lineIndex) => calls.focusTextareaAtLine.push(lineIndex),
refreshCaretLogicalLine: () => {
calls.refreshCaret += 1
},
scrollPreviewToTop: () => {
calls.scrollPreviewToTop += 1
},
focusPreviewEditableAtLine: (...args) => calls.focusPreview.push(args)
})
return {
actions,
activeLogicalLineIndex,
activeMode,
calls,
textarea,
value
}
}
test('관리자 Markdown 첫 포커스 줄은 첫 줄 제목 다음 줄을 선택한다', () => {
const state = createEditorFocusActionsState({
value: '# 제목'
})
assert.equal(state.actions.getInitialContentFocusLineIndex(), 1)
assert.equal(state.actions.ensureContentFocusLineExists(1), 1)
assert.equal(state.value.value, '# 제목\n')
})
test('관리자 Markdown 첫 블록 포커스는 작성 모드 textarea를 문서 상단으로 맞춘다', async () => {
const state = createEditorFocusActionsState({
value: '# 제목',
activeMode: 'write'
})
state.actions.focusFirstBlock()
await nextTick()
assert.equal(state.value.value, '# 제목\n')
assert.deepEqual(state.textarea.selection, { start: 5, end: 5 })
assert.equal(state.textarea.scrollTop, 0)
assert.equal(state.textarea.focused, true)
assert.equal(state.activeLogicalLineIndex.value, 1)
assert.equal(state.calls.refreshCaret, 1)
})
test('관리자 Markdown 첫 블록 포커스는 라이브 모드에서 상단 이동 후 편집 줄을 선택한다', async () => {
const state = createEditorFocusActionsState({
value: '# 제목\n본문',
activeMode: 'preview'
})
state.actions.focusFirstBlock()
await nextTick()
await nextTick()
assert.equal(state.calls.scrollPreviewToTop, 1)
assert.deepEqual(state.calls.focusPreview, [[1, 0, 'start']])
})
test('관리자 Markdown 히스토리 복원 포커스는 작성 모드 선택 범위를 보존 스크롤로 복원한다', () => {
const state = createEditorFocusActionsState({
activeMode: 'write'
})
state.actions.restoreEditorFocusAfterHistory({ start: 3, end: 5 })
assert.deepEqual(state.calls.setTextareaSelection, [{
start: 3,
end: 5,
options: { preserveScroll: true }
}])
assert.deepEqual(state.calls.focusTextareaAtLine, [])
})
test('관리자 Markdown 히스토리 복원 포커스는 라이브 모드 줄과 오프셋을 복원한다', async () => {
const state = createEditorFocusActionsState({
value: '첫 줄\n둘째 줄',
activeMode: 'preview'
})
state.actions.restoreEditorFocusAfterHistory({ start: 6, end: 6 })
await nextTick()
assert.deepEqual(state.calls.focusPreview, [[1, 0, 'auto', 2, 'center']])
})
test('관리자 Markdown 히스토리 복원 선택이 없으면 현재 논리 줄로 작성 포커스를 보낸다', () => {
const state = createEditorFocusActionsState({
activeMode: 'write',
activeLogicalLineIndex: 2
})
state.actions.restoreEditorFocusAfterHistory()
assert.deepEqual(state.calls.focusTextareaAtLine, [2])
})