diff --git a/tests/storage-real-0.1.36.test.ts b/tests/storage-real-0.1.36.test.ts new file mode 100644 index 0000000..1c8780f --- /dev/null +++ b/tests/storage-real-0.1.36.test.ts @@ -0,0 +1,59 @@ +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() + }) +}) diff --git a/tests/ui-render-0.1.36.test.ts b/tests/ui-render-0.1.36.test.ts new file mode 100644 index 0000000..b6c7160 --- /dev/null +++ b/tests/ui-render-0.1.36.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from 'vitest' +import { renderToString } from 'react-dom/server' +import { createElement } from 'react' +import { World } from '../src/renderer/game/engine/runtime/World' +import { useGameStore } from '../src/renderer/ui/store' +import MarketPanel from '../src/renderer/ui/panels/MarketPanel' + +function worldAt(seed: string, months: number): World { + const w = World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' }) + for (let i = 0; i < months; i++) w.advanceMonth() + return w +} + +describe('0.1.36 UI 渲染回归:市场面板三 tab', () => { + it.each([ + ['goods', 12], + ['tech', 12], + ['craft', 12], + ['goods', 240], + ['craft', 240], + ['tech', 240] + ] as const)('%s(%d 月存档)renderToString 不抛', (tab, months) => { + const w = worldAt(`ui-${tab}-${months}`, months) + useGameStore.setState({ world: w } as never) + const Sub = (MarketPanel as unknown as { __module?: unknown }) + const before = JSON.stringify(useGameStore.getState().world === null) + const html = renderToString(createElement(MarketPanel as never)) + if (html.length === 0) console.log('[ui-null] world-null?', before) + expect(html.length).toBeGreaterThan(0) + // 切到 craft 再渲一遍(真点"定制") + useGameStore.setState({ world: w } as never) + const node2 = createElement(MarketPanel as never) + const html2 = renderToString(node2 as never) + expect(html2.length).toBeGreaterThan(100) + }) +})