import { describe, it, expect, beforeEach, vi } from 'vitest' import { buildTree, sortTree } from '@/utils/tree' describe('utils/tree buildTree', () => { it('空数组返回空树', () => { expect(buildTree([])).toEqual([]) }) it('无父节点的节点成为根', () => { const list = [ { b_id: 1, b_parent_id: null }, { b_id: 2, b_parent_id: null }, ] const tree = buildTree(list) expect(tree).toHaveLength(2) expect(tree.map((n) => n.b_id)).toEqual([1, 2]) }) it('按 parentKey 挂载子节点', () => { const list = [ { b_id: 1, b_parent_id: null }, { b_id: 2, b_parent_id: 1 }, { b_id: 3, b_parent_id: 2 }, ] const tree = buildTree(list) expect(tree).toHaveLength(1) expect(tree[0].b_id).toBe(1) expect(tree[0].children).toHaveLength(1) expect(tree[0].children[0].b_id).toBe(2) expect(tree[0].children[0].children[0].b_id).toBe(3) }) it('父节点不存在的子节点提升为根(孤儿节点)', () => { const list = [ { b_id: 2, b_parent_id: 999 }, { b_id: 3, b_parent_id: null }, ] const tree = buildTree(list) expect(tree).toHaveLength(2) }) it('支持自定义 idKey / parentKey / childrenKey', () => { const list = [ { id: 'a', pid: null }, { id: 'b', pid: 'a' }, ] const tree = buildTree(list, 'id', 'pid', 'kids') expect(tree[0].kids[0].id).toBe('b') }) it('副作用说明:向父节点对象注入 children 属性(当前实现行为)', () => { const list = [ { b_id: 1, b_parent_id: null }, { b_id: 2, b_parent_id: 1 }, ] buildTree(list) // 当前实现直接修改传入的节点对象(parent[childrenKey] = []), // 调用方若复用原数组需注意此副作用;若要求纯函数需后续改造 expect(Array.isArray(list[0].children)).toBe(true) expect(list[0].children).toHaveLength(1) }) }) describe('utils/tree sortTree', () => { it('按 b_xh 升序排序', () => { const tree = [{ b_xh: 3 }, { b_xh: 1 }, { b_xh: 2 }] sortTree(tree) expect(tree.map((n) => n.b_xh)).toEqual([1, 2, 3]) }) it('b_xh 相同按 b_id 排序', () => { const tree = [{ b_xh: 1, b_id: 'b' }, { b_xh: 1, b_id: 'a' }] sortTree(tree) expect(tree.map((n) => n.b_id)).toEqual(['a', 'b']) }) it('递归排序子节点', () => { const tree = [ { b_xh: 1, children: [{ b_xh: 2 }, { b_xh: 1 }], }, ] sortTree(tree) expect(tree[0].children.map((n) => n.b_xh)).toEqual([1, 2]) }) it('返回原数组引用', () => { const tree = [{ b_xh: 2 }, { b_xh: 1 }] expect(sortTree(tree)).toBe(tree) }) }) describe('utils/theme', () => { beforeEach(() => { document.documentElement.style.cssText = '' document.documentElement.classList.remove('dark') }) it('applyPrimaryColor 写入 --fms-primary CSS 变量', async () => { const { applyPrimaryColor } = await import('@/theme/index') applyPrimaryColor('#ff0000') expect(document.documentElement.style.getPropertyValue('--fms-primary')).toBe('#ff0000') }) it('applyPrimaryColor 空值不写入', async () => { const { applyPrimaryColor } = await import('@/theme/index') applyPrimaryColor('') expect(document.documentElement.style.getPropertyValue('--fms-primary')).toBe('') }) it('applyDarkMode true 添加 dark class,false 移除', async () => { const { applyDarkMode } = await import('@/theme/index') applyDarkMode(true) expect(document.documentElement.classList.contains('dark')).toBe(true) applyDarkMode(false) expect(document.documentElement.classList.contains('dark')).toBe(false) }) })