73 lines
3.9 KiB
TypeScript
73 lines
3.9 KiB
TypeScript
import type { WrittenBlock } from './testBlocks'
|
||
import type { BlockView } from './types'
|
||
import { describe, expect, it } from 'vitest'
|
||
import { coveredByEditing, startEditing } from './editing'
|
||
import { placementOf } from './placement'
|
||
import { revealPlan, uncoveredPlan } from './reveal'
|
||
import { placed } from './testBlocks'
|
||
|
||
function block(id: string, kind: string, lines: [number, number], children: WrittenBlock[] = []): WrittenBlock {
|
||
return { id, anchor: id, kind, lines, attributes: { kind }, concepts: [{ id: kind, label: kind, icon: 'box' }], children, properties: [] }
|
||
}
|
||
|
||
/**
|
||
* 编辑范围是块的完整源码:库规则的卡片(1)是整个类(2–12 行),两个字段中间写着的方法(1.0)和它的主体(1.0.0)、
|
||
* 类末尾的方法(1.1)都在这段里;普通的类(2)同样盖住它的方法(2.0);`} else {` 写在一行时 if(3)和 else(4)共用第 20 行。
|
||
*/
|
||
const BLOCKS = placed([
|
||
block('0', 'import', [0, 0]),
|
||
block('1', 'sqlalchemy.table', [2, 12], [
|
||
block('1.0', 'function', [5, 6], [block('1.0.0', 'return', [6, 6])]),
|
||
block('1.1', 'function', [11, 12]),
|
||
]),
|
||
block('2', 'class', [14, 16], [block('2.0', 'function', [15, 16])]),
|
||
block('3', 'if', [18, 20], [block('3.0', 'return', [19, 19])]),
|
||
block('4', 'else', [20, 22], [block('4.0', 'return', [21, 21])]),
|
||
])
|
||
const PLACEMENT = placementOf(BLOCKS)
|
||
|
||
describe('同一行不会同时在两处能改', () => {
|
||
it('块编辑时它的子孙都不画(代码都在它的编辑框里),跳到它们时改闪它', () => {
|
||
expect(coveredByEditing(BLOCKS, new Set(['1']))).toEqual(new Map([['1.0', '1'], ['1.0.0', '1'], ['1.1', '1']]))
|
||
expect(coveredByEditing(BLOCKS, new Set(['2']))).toEqual(new Map([['2.0', '2']]))
|
||
})
|
||
|
||
it('子块编辑时只盖住它自己的子孙,父块、兄弟块照常画', () => {
|
||
expect(coveredByEditing(BLOCKS, new Set(['1.0']))).toEqual(new Map([['1.0.0', '1.0']]))
|
||
expect(coveredByEditing(BLOCKS, new Set(['1.1', '3']))).toEqual(new Map([['3.0', '3']]))
|
||
})
|
||
|
||
it('祖先和子孙都记着在编辑时(文档刷新前的状态),算页面上画着的最外层那块', () => {
|
||
expect(coveredByEditing(BLOCKS, new Set(['1', '1.0']))).toEqual(new Map([['1.0', '1'], ['1.0.0', '1'], ['1.1', '1']]))
|
||
})
|
||
|
||
it('点「编辑」:编辑范围和它重叠的别的块(祖先、子孙、共用一行的兄弟块)退出编辑,不重叠的留着', () => {
|
||
expect(startEditing(PLACEMENT, ['1.0', '1.1', '2'], '1')).toEqual(['2', '1'])
|
||
expect(startEditing(PLACEMENT, ['1', '2'], '1.0')).toEqual(['2', '1.0'])
|
||
expect(startEditing(PLACEMENT, ['2'], '2.0')).toEqual(['2.0'])
|
||
expect(startEditing(PLACEMENT, ['0', '3'], '4')).toEqual(['0', '4'])
|
||
})
|
||
|
||
it('任何时候正在编辑、画出来的几块,编辑范围两两不重叠', () => {
|
||
const all = (list: BlockView[]): BlockView[] => list.flatMap(item => [item, ...all(item.children)])
|
||
let editing: string[] = []
|
||
for (const id of ['1.0', '1.0.0', '2', '2.0', '1', '3.0', '3', '4', '1.1'])
|
||
editing = startEditing(PLACEMENT, editing, id)
|
||
const covered = coveredByEditing(BLOCKS, new Set(editing))
|
||
const shown = all(BLOCKS).filter(item => editing.includes(item.id) && !covered.has(item.id))
|
||
for (const a of shown) {
|
||
for (const b of shown.filter(other => other !== a)) {
|
||
const [x, y] = [PLACEMENT.of(a.id)!, PLACEMENT.of(b.id)!]
|
||
expect(x.line > y.endLine || y.line > x.endLine, `${a.id} / ${b.id}`).toBe(true)
|
||
}
|
||
}
|
||
})
|
||
|
||
it('跳到定义的目标被盖住:闪盖住它的那块,展开那块的祖先', () => {
|
||
const covered = coveredByEditing(BLOCKS, new Set(['1']))
|
||
expect(uncoveredPlan({ id: '1.0.0', expand: ['1', '1.0'] }, covered)).toEqual({ id: '1', expand: [] })
|
||
const plain = revealPlan(BLOCKS, PLACEMENT, 15, 999)
|
||
expect(plain && uncoveredPlan(plain, covered)).toEqual(plain)
|
||
})
|
||
})
|