/** * 01-boot — 核心初始化:FS、Bus、Store * * 纯 composable 层测试,不依赖 DOM / Vue。 * 使用 vitest 原汁原味的 vi.fn() + beforeEach 模式。 */ import { describe, it, expect, beforeEach, vi } from 'vitest' import { bus } from '../../src/composables/useBus' import { store } from '../../src/composables/useStore' import { fs } from '../../src/composables/useFS' describe('01-boot — 核心初始化', () => { beforeEach(() => { localStorage.clear() // 重置 fs 内部状态 ;(fs as any).root = null fs.init() }) // ==================== FS 文件系统 ==================== describe('FS 文件系统', () => { it('根节点类型为目录', () => { expect(fs.root!.t).toBe('d') }) it('home 目录存在', () => { expect(fs.exists(fs.HOME)).toBe(true) }) it('Desktop 目录存在', () => { expect(fs.exists(fs.HOME + '/Desktop')).toBe(true) }) it('welcome.txt 存在且包含欢迎语', () => { expect(fs.exists(fs.HOME + '/Desktop/welcome.txt')).toBe(true) expect(fs.read(fs.HOME + '/Desktop/welcome.txt')).toContain('欢迎使用 macOS 网页版') }) }) // ==================== Bus 事件总线 ==================== describe('Bus 事件总线', () => { it('基本发布订阅', () => { const handler = vi.fn() const unsub = bus.on('test-event', handler) bus.emit('test-event', { value: 42 }) expect(handler).toHaveBeenCalledTimes(1) expect(handler).toHaveBeenCalledWith({ value: 42 }) unsub() }) it('取消订阅后不再触发', () => { const handler = vi.fn() const unsub = bus.on('test-event', handler) unsub() bus.emit('test-event') expect(handler).not.toHaveBeenCalled() }) it('多个订阅者都收到事件', () => { const h1 = vi.fn(), h2 = vi.fn() const u1 = bus.on('multi', h1), u2 = bus.on('multi', h2) bus.emit('multi') expect(h1).toHaveBeenCalledTimes(1) expect(h2).toHaveBeenCalledTimes(1) u1(); u2() }) it('emit 无订阅者不抛错', () => { expect(() => bus.emit('no-listener')).not.toThrow() }) }) // ==================== Store 持久化 ==================== describe('Store 持久化', () => { it('set/get 基本读写', () => { store.set('test-key', { v: 1 }) expect(store.get('test-key', null)).toEqual({ v: 1 }) }) it('get 不存在的 key 返回 fallback', () => { expect(store.get('nonexistent', { default: true })).toEqual({ default: true }) }) it('remove 后返回 fallback', () => { store.set('test-key', 'value') store.remove('test-key') expect(store.get('test-key', 'fallback')).toBe('fallback') }) }) })