165 lines
5.1 KiB
JavaScript
165 lines
5.1 KiB
JavaScript
/**
|
|
* 往来单位分类树页面级纯函数(views/base/othercompany/utils.js)。
|
|
*
|
|
* 重点是 buildCategoryTree 不能污染原始行:buildTree 会就地往行对象上挂 children,
|
|
* 若直接在 categories 的行上构建,重复构建会累积出重复子节点。
|
|
*/
|
|
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
ALL_CATEGORY_KEY,
|
|
addRowUpdate,
|
|
applyCategoryPosition,
|
|
buildCategoryTree,
|
|
findNodePosition,
|
|
hasChildCategory,
|
|
nextSiblingXh,
|
|
rebuildTreePositions,
|
|
renumberSiblings,
|
|
} from '@/views/base/othercompany/utils'
|
|
|
|
function category(over = {}) {
|
|
return {
|
|
b_id: 'a',
|
|
b_parent_id: null,
|
|
b_depth: 0,
|
|
b_path: '/a/',
|
|
b_name: 'A',
|
|
b_xh: 10,
|
|
b_canuse: 1,
|
|
...over,
|
|
}
|
|
}
|
|
|
|
describe('othercompany 分类树工具:buildCategoryTree', () => {
|
|
it('按 b_parent_id 建树并按 b_xh 排序', () => {
|
|
const rows = [
|
|
category({ b_id: 'b', b_xh: 20, b_name: 'B' }),
|
|
category({ b_id: 'a', b_xh: 10, b_name: 'A' }),
|
|
category({ b_id: 'a1', b_parent_id: 'a', b_depth: 1, b_path: '/a/a1/', b_name: 'A1' }),
|
|
]
|
|
|
|
const tree = buildCategoryTree(rows)
|
|
|
|
expect(tree.map((node) => node.b_id)).toEqual(['a', 'b'])
|
|
expect(tree[0].children.map((node) => node.b_id)).toEqual(['a1'])
|
|
})
|
|
|
|
it('不污染原始行,重复构建不会累积出重复子节点', () => {
|
|
const rows = [
|
|
category({ b_id: 'a' }),
|
|
category({ b_id: 'a1', b_parent_id: 'a', b_depth: 1, b_path: '/a/a1/' }),
|
|
]
|
|
|
|
buildCategoryTree(rows)
|
|
// buildTree 的 children 挂在浅拷贝上,原始行保持干净
|
|
expect(rows[0].children).toBeUndefined()
|
|
|
|
const tree = buildCategoryTree(rows)
|
|
expect(tree[0].children).toHaveLength(1)
|
|
expect(tree[0].children[0].b_id).toBe('a1')
|
|
})
|
|
})
|
|
|
|
describe('othercompany 分类树工具:位置派生', () => {
|
|
it('根节点的 b_depth 为 0、b_path 为 /编码/', () => {
|
|
const row = { b_id: 'a' }
|
|
applyCategoryPosition(row, null)
|
|
expect(row).toMatchObject({ b_depth: 0, b_path: '/a/' })
|
|
})
|
|
|
|
it('子节点继承父级路径并递增层级', () => {
|
|
const row = { b_id: 'a1' }
|
|
applyCategoryPosition(row, { b_depth: 2, b_path: '/a/b/' })
|
|
expect(row).toMatchObject({ b_depth: 3, b_path: '/a/b/a1/' })
|
|
})
|
|
})
|
|
|
|
describe('othercompany 分类树工具:排序号与子分类判定', () => {
|
|
it('同级最大 b_xh 加 10,无同级时取 10', () => {
|
|
const rows = [
|
|
category({ b_id: 'a', b_xh: 10 }),
|
|
category({ b_id: 'b', b_xh: 30 }),
|
|
category({ b_id: 'a1', b_parent_id: 'a', b_xh: 90 }),
|
|
]
|
|
|
|
expect(nextSiblingXh(rows, null)).toBe(40)
|
|
expect(nextSiblingXh(rows, 'a')).toBe(100)
|
|
expect(nextSiblingXh(rows, 'not-exist')).toBe(10)
|
|
expect(nextSiblingXh([], null)).toBe(10)
|
|
})
|
|
|
|
it('hasChildCategory 只看直接子分类', () => {
|
|
const rows = [
|
|
category({ b_id: 'a' }),
|
|
category({ b_id: 'a1', b_parent_id: 'a' }),
|
|
category({ b_id: 'a1x', b_parent_id: 'a1' }),
|
|
]
|
|
|
|
expect(hasChildCategory(rows, 'a')).toBe(true)
|
|
expect(hasChildCategory(rows, 'a1')).toBe(true)
|
|
expect(hasChildCategory(rows, 'a1x')).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('othercompany 分类树工具:重排与重建位置', () => {
|
|
it('renumberSiblings 按 10 步长重排并只收集变化的行', () => {
|
|
const a = { b_id: 'a', b_xh: 30 }
|
|
const b = { b_id: 'b', b_xh: 10 }
|
|
const updated = []
|
|
|
|
renumberSiblings([a, b], updated)
|
|
|
|
expect([a.b_xh, b.b_xh]).toEqual([10, 20])
|
|
expect(updated).toEqual([
|
|
{ b_id: 'a', b_xh: 10 },
|
|
{ b_id: 'b', b_xh: 20 },
|
|
])
|
|
})
|
|
|
|
it('rebuildTreePositions 整树收敛 b_depth / b_path,未变化的不重复收集', () => {
|
|
const tree = [
|
|
{
|
|
b_id: 'a',
|
|
b_depth: 0,
|
|
b_path: '/a/',
|
|
children: [{ b_id: 'a1', b_depth: 9, b_path: '/stale/', children: [] }],
|
|
},
|
|
]
|
|
const updated = []
|
|
|
|
rebuildTreePositions(tree, updated)
|
|
|
|
expect(tree[0].children[0]).toMatchObject({ b_depth: 1, b_path: '/a/a1/' })
|
|
// 根节点本来就是 0 / '/a/',不该产生一条无意义的 update
|
|
expect(updated).toEqual([{ b_id: 'a1', b_depth: 1, b_path: '/a/a1/' }])
|
|
})
|
|
|
|
it('addRowUpdate 按 b_id 合并字段,避免同节点多条 update', () => {
|
|
const updated = []
|
|
addRowUpdate(updated, { b_id: 'a', b_xh: 20 })
|
|
addRowUpdate(updated, { b_id: 'a', b_parent_id: 'p' })
|
|
addRowUpdate(updated, { b_id: 'b', b_xh: 10 })
|
|
|
|
expect(updated).toEqual([
|
|
{ b_id: 'a', b_xh: 20, b_parent_id: 'p' },
|
|
{ b_id: 'b', b_xh: 10 },
|
|
])
|
|
})
|
|
|
|
it('findNodePosition 返回所在父数组与索引', () => {
|
|
const tree = [{ b_id: 'a', children: [{ b_id: 'a1' }, { b_id: 'a2' }] }]
|
|
|
|
expect(findNodePosition(tree, 'a')).toMatchObject({ index: 0 })
|
|
const found = findNodePosition(tree, 'a2')
|
|
expect(found.index).toBe(1)
|
|
expect(found.list.map((node) => node.b_id)).toEqual(['a1', 'a2'])
|
|
expect(findNodePosition(tree, 'not-exist')).toBe(null)
|
|
})
|
|
})
|
|
|
|
describe('othercompany 分类树工具:虚拟根键', () => {
|
|
it('与 FmsTree 的 rootKey 约定保持一致', () => {
|
|
expect(ALL_CATEGORY_KEY).toBe('__fms_tree_root__')
|
|
})
|
|
})
|