Files
ChronicleOfTheImmortalClan/tests/storage-real-0.1.36.test.ts
T
thzxx 73fa9eb7f2 test: 存储真链集成测试(MetonaSqlark memory 方言——非 mock)——save/load/export/slot 管理 6 种子全链
此前所有存量测试用 SaveDbDriver mock——真实 SQL 方言链从未被 vitest 覆盖(唯一 GUI 冒烟因环境不可用);
本测试直接注入 MeSqlark memory 后端:saveState→list→loadState→resume advance→exportAll→slot 管理面/remove;
为 0.1.36 三问题(推进崩溃/存档丢失)提供真实存储链防线;+1 套件
2026-08-24 21:59:00 +08:00

60 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest'
import { MeSqlark } from '@metona-team/metona-sqlark'
import { setSqlarkBackend } from '../src/renderer/game/storage/db'
import { getSaveSlot } from '../src/renderer/game/storage/db'
import { World } from '../src/renderer/game/engine/runtime/World'
import { metaFromState } from '../src/renderer/ui/storeHelper'
import type { GameState } from '../src/renderer/game/types/domain'
import type { SaveDbDriver } from '../src/renderer/game/storage/slots'
function memoryBackend(): void {
setSqlarkBackend({
create: async (cfg: { name: string }) => {
const db = new MeSqlark({
name: `it-${cfg.name}-${Math.random().toString(36).slice(2)}`,
mode: 'hybrid',
diskEngine: 'memory',
aria: {}
})
await db.init()
return { query: (sql: string, params?: unknown[]) => db.query(sql, params) }
}
} as never)
}
function saveClone(w: World): GameState {
return JSON.parse(JSON.stringify(w.state)) as GameState
}
describe('0.1.36 存储真链(MetonaSqlark memory 方言——非 mock', () => {
it('save→list→load→resume→save 全链 12 种子不崩', async () => {
memoryBackend()
for (let k = 0; k < 6; k++) {
const slot = (k % 4) + 1
const w = World.create({ seed: `real-${k}`, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
for (let i = 0; i < 12; i++) w.advanceMonth()
const file = await getSaveSlot(slot)
const file2 = await getSaveSlot(slot)
await file.open()
await file.saveState(saveClone(w), '自动')
const meta = metaFromState(w.state, slot)
await file.setMeta(meta)
const loaded = await file2.loadState()
expect(loaded).toBeTruthy()
expect(loaded!.year).toBeGreaterThan(0)
const y = new World(loaded!)
for (let i = 0; i < 8; i++) y.advanceMonth()
const exportStr = await file.exportAll()
expect(exportStr.length).toBeGreaterThan(100)
}
// slot 管理面
const { getSlotManager } = await import('../src/renderer/game/storage/db')
const mgr = getSlotManager()
const metas = await mgr.listSlotMetas()
expect(metas.length).toBe(4)
await mgr.updateSlotMeta(1, { slot: 1, surname: '钟', name: '钟家', estate: '青云庄', year: 3, month: 4, generation: 1, members: 5, reputation: 5, updatedAt: 'x', version: '0.1.35' })
await mgr.removeSlotMeta(1)
expect((await mgr.listSlotMetas())[0]).toBeNull()
})
})