feat: rename app to Qiyun and refine Tiangong rituals and UI
This commit is contained in:
1 parent
7871114c50
commit
df84a4c130
32 files changed
+482
-130
No files matched your search
@@ -5,15 +5,16 @@ const path = require('node:path')
|
||||
const vm = require('node:vm')
|
||||
const ts = require('typescript')
|
||||
const root = path.resolve(__dirname, '..')
|
||||
function page(file, { bound = false, demo = false, modal = '', detail = 'https://example.invalid/detail.png', description = '后端返回的介绍\n保留换行' } = {}) {
|
||||
function page(file, { bound = false, demo = false, modal = '', detail = 'https://example.invalid/detail.png', description = '后端返回的介绍\n保留换行', latestPrayer = null, latestDedication = null } = {}) {
|
||||
const deity = { id: 'wealth', name: '财神', ritualName: '武财神', icon: 'local-list.png', statue: 'local-statue.png', introduction: '本地原型介绍', missingStatue: true }
|
||||
const state = { available: true, unlocked: bound, iconUrl: 'https://example.invalid/list.png', iconDetailUrl: detail, description, days: 4, incenseCount: 12 }
|
||||
const state = { available: true, unlocked: bound, iconUrl: 'https://example.invalid/list.png', iconDetailUrl: detail, description, days: 4, incenseCount: 12, latestPrayer, latestDedication }
|
||||
const states = []; let index = 0
|
||||
const exports = {}
|
||||
vm.runInNewContext(ts.transpileModule(fs.readFileSync(path.join(root, file), 'utf8'), { compilerOptions: {
|
||||
module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2019, jsx: ts.JsxEmit.ReactJSX
|
||||
} }).outputText, { exports, require: id => {
|
||||
if (id === 'react/jsx-runtime') return require(id)
|
||||
if (id.endsWith('.jpg')) return { default: id }
|
||||
if (id === 'react') return { useRef: value => ({ current: value }), useState: initial => {
|
||||
const current = index++
|
||||
if (!(current in states)) states[current] = current === 1 && file.includes('tiangong-detail') ? modal : initial
|
||||
@@ -39,6 +40,42 @@ function nodes(tree) {
|
||||
}
|
||||
const text = tree => nodes(tree).filter(node => node.type === 'Text').map(node => node.props.children).flat().join(' ')
|
||||
const image = tree => nodes(tree).filter(node => node.type === 'Image')
|
||||
const statueImages = tree => image(tree).filter(node => /tg-statue|tg-panel-statue/.test(node.props.className))
|
||||
test('打开祈愿回填最新内容,编辑中不被查询快照覆盖,再次打开恢复已保存内容', () => {
|
||||
const render = page('src/pages/tiangong-detail/index.tsx', { bound: true, latestPrayer: { prayerContent: '已保存的愿望' } })
|
||||
const openWish = () => nodes(render()).find(node => node.props['aria-label'] === '祈愿').props.onClick()
|
||||
const input = () => nodes(render()).find(node => node.type === 'Textarea')
|
||||
openWish()
|
||||
assert.equal(input().props.value, '已保存的愿望')
|
||||
input().props.onInput({ detail: { value: '正在编辑的新愿望' } })
|
||||
assert.equal(input().props.value, '正在编辑的新愿望')
|
||||
nodes(render()).find(node => node.type === 'Button' && node.props.children === '取消').props.onClick()
|
||||
openWish()
|
||||
assert.equal(input().props.value, '已保存的愿望')
|
||||
})
|
||||
test('打开回向回填对象及可选祝愿,没有可用记录时均为空', () => {
|
||||
for (const latestDedication of [null, { dedicationTarget: '家人', dedicationContent: '平安顺遂' }, { dedicationTarget: '一切众生', dedicationContent: null }]) {
|
||||
const render = page('src/pages/tiangong-detail/index.tsx', { bound: true, latestDedication })
|
||||
nodes(render()).find(node => node.props['aria-label'] === '回向').props.onClick()
|
||||
assert.equal(nodes(render()).find(node => node.type === 'Input').props.value, latestDedication?.dedicationTarget || '')
|
||||
assert.equal(nodes(render()).find(node => node.type === 'Textarea').props.value, latestDedication?.dedicationContent || '')
|
||||
}
|
||||
const render = page('src/pages/tiangong-detail/index.tsx', { bound: true })
|
||||
nodes(render()).find(node => node.props['aria-label'] === '祈愿').props.onClick()
|
||||
assert.equal(nodes(render()).find(node => node.type === 'Textarea').props.value, '')
|
||||
})
|
||||
test('请神和敬神均用原生图片加载本地山水,背景位于神像下方', () => {
|
||||
for (const bound of [true, false]) {
|
||||
const tree = page('src/pages/tiangong-detail/index.tsx', { bound })()
|
||||
const scene = nodes(tree).find(node => node.props.className === 'tg-statue-space')
|
||||
assert.equal(scene.props.style?.backgroundImage, undefined)
|
||||
const background = scene.props.children[0]
|
||||
assert.equal(background.type, 'Image')
|
||||
assert.equal(background.props.className, 'tg-scene-background')
|
||||
assert.match(background.props.src, /proto-clouds\.jpg$/)
|
||||
assert.equal(background.props.mode, bound ? 'aspectFill' : 'scaleToFill')
|
||||
}
|
||||
})
|
||||
test('详情及弹窗均使用详情图;仅请神页展示description,敬神页不展示介绍', () => {
|
||||
for (const bound of [true, false]) {
|
||||
const tree = page('src/pages/tiangong-detail/index.tsx', { bound, modal: 'wish' })()
|
||||
@@ -66,12 +103,13 @@ test('敬神页在正式和Demo模式均不显示介绍,缺少介绍也不显
|
||||
test('真实字段为空或加载失败时提示,不以本地神像、列表缩略图或原型介绍顶替', () => {
|
||||
const empty = page('src/pages/tiangong-detail/index.tsx', { detail: '', description: '' })()
|
||||
assert.match(text(empty), /详情图片暂未配置/); assert.match(text(empty), /暂无介绍/)
|
||||
assert.equal(image(empty).length, 0)
|
||||
assert.equal(statueImages(empty).length, 0)
|
||||
const render = page('src/pages/tiangong-detail/index.tsx')
|
||||
image(render())[0].props.onError()
|
||||
statueImages(render())[0].props.onError()
|
||||
const failed = render()
|
||||
assert.match(text(failed), /详情图片加载失败/)
|
||||
assert.equal(image(failed).length, 0)
|
||||
assert.equal(statueImages(failed).length, 0)
|
||||
assert.ok(image(failed).some(node => node.props.className === 'tg-scene-background'))
|
||||
})
|
||||
test('列表保留iconUrl与20%透明度规则,详情字段不误用到列表;显式Demo保留原型', () => {
|
||||
for (const bound of [true, false]) {
|
||||
@@ -82,6 +120,6 @@ test('列表保留iconUrl与20%透明度规则,详情字段不误用到列表
|
||||
}
|
||||
assert.match(fs.readFileSync(path.join(root, 'src/pages/fortune/index.scss'), 'utf8'), /\.deity-card\.locked \.deity-image \{ opacity: \.2; \}/)
|
||||
const demo = page('src/pages/tiangong-detail/index.tsx', { demo: true })()
|
||||
assert.equal(image(demo)[0].props.src, 'local-statue.png')
|
||||
assert.equal(statueImages(demo)[0].props.src, 'local-statue.png')
|
||||
assert.match(text(demo), /本地原型介绍/)
|
||||
})
|
||||
Reference in new issue
Block a user