52 lines
2.3 KiB
TypeScript
52 lines
2.3 KiB
TypeScript
import { readFileSync } from 'fs'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const readClientFile = (path: string) => readFileSync(`packages/client/src/${path}`, 'utf8')
|
|
|
|
// 从 `computed(` 的左括号开始做括号配平,精确切出这个表达式的范围。
|
|
// 用空行切分不行:箭头函数写成单行后,紧邻的下一个顶层声明只隔一个空行。
|
|
function balancedBlock(source: string, header: string): string {
|
|
const start = source.indexOf(header)
|
|
expect(start, `${header} not found`).toBeGreaterThan(-1)
|
|
|
|
let depth = 0
|
|
for (let i = start + header.length - 1; i < source.length; i += 1) {
|
|
if (source[i] === '(') depth += 1
|
|
if (source[i] === ')') {
|
|
depth -= 1
|
|
if (depth === 0) return source.slice(start, i + 1)
|
|
}
|
|
}
|
|
return source.slice(start)
|
|
}
|
|
|
|
// known-issues #1: `providerOptions` 的 computed getter 内部给 customProvider
|
|
// 赋值。用户手动挑好的 provider 会被下一次 getter 重算无声改回去,表现为
|
|
// 「自己跳」。修法是把同步移进 watch,让 getter 恢复成纯读。
|
|
describe('ModelSelector provider selection', () => {
|
|
it('keeps the providerOptions getter free of side effects', () => {
|
|
const source = readClientFile('components/layout/ModelSelector.vue')
|
|
const block = balancedBlock(source, 'const providerOptions = computed(')
|
|
|
|
expect(block).not.toContain('customProvider.value =')
|
|
})
|
|
|
|
it('syncs customProvider from the store through a watch', () => {
|
|
const source = readClientFile('components/layout/ModelSelector.vue')
|
|
const block = balancedBlock(source, 'watch(')
|
|
|
|
// 同步点必须挂在 selectedProvider 上,而不是挂在 providerOptions 上 ——
|
|
// 后者等于把同一个副作用换个地方写一遍。
|
|
expect(block.slice(0, 200)).toContain('appStore.selectedProvider')
|
|
expect(block).toContain('customProvider.value =')
|
|
})
|
|
|
|
it('still initialises the provider when the picker opens', () => {
|
|
// watch 是懒的:不会在初始渲染时触发。openModal 的这一次赋值是首帧
|
|
// 唯一来源,不能跟着一起去掉。
|
|
const source = readClientFile('components/layout/ModelSelector.vue')
|
|
|
|
expect(source).toMatch(/function openModal\(\)[\s\S]*?customProvider\.value = appStore\.selectedProvider/)
|
|
})
|
|
})
|