에디터 공통 포커스 실행 분리
This commit is contained in:
143
tests/useAdminMarkdownEditorFocusActions.test.js
Normal file
143
tests/useAdminMarkdownEditorFocusActions.test.js
Normal file
@@ -0,0 +1,143 @@
|
||||
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])
|
||||
})
|
||||
Reference in New Issue
Block a user