import { insertTreeRow, deleteTreeRow, getInsertAtIndex, pushTreeRow, // getNewRowDimensions, inferHostRowsByInsert, inferHostRowsByPush, } from './row'; import { IStoreState, IRow, ICell } from '../../index.data'; import { IRowWithCell } from '../../SpreadSheetProvider/index.data'; import { idMap } from 'valor-app-utils'; describe('insertRow', () => { const rows: IRow[] = [ { id: 1, level: 1, i: 0, type: 'body', cellIds: [1], }, ]; const cells: ICell[] = [ { id: 1, rowId: 1, i: 0, j: 0, value: 1, formula: 'sumChildren()', formulaDisabled: true, }, ]; const state = ({ columns: [{ type: 'text' }], rows, cells: idMap(cells), treeContext: { '-1': { childrenIds: [1] }, 1: { childrenIds: [] }, }, } as any) as IStoreState; console.warn('本方法假定参数是正常的, 因此不检查 0行等情形'); const rowsToInsert: IRowWithCell[] = [ { id: 100, level: 1, i: 0, type: 'body', cells: [ { id: 100, rowId: 100, i: 0, j: 0, value: 100, formula: 'sumChildren()', formulaDisabled: false, }, ], }, { id: 101, level: 2, i: 1, type: 'body', cells: [{ id: 101, rowId: 101, i: 1, j: 0, value: 100 }], }, { id: 102, level: 2, i: 2, type: 'body', cells: [{ id: 102, rowId: 102, i: 2, j: 0, value: 100 }], }, ]; it('case0: 插入子树为兄弟(可以容纳插入单行情形)', () => { const result = insertTreeRow( state, 'sibling', 0, rowsToInsert, undefined as any, undefined as any, undefined as any, ); const expected = { rows: [ { id: 1, level: 1, i: 0, type: 'body', cellIds: [1], }, { id: 100, level: 1, i: 1, type: 'body', cellIds: [100], }, { id: 101, level: 2, i: 2, type: 'body', cellIds: [101] }, { id: 102, level: 2, i: 3, type: 'body', cellIds: [102], }, ], cells: { 1: { id: 1, rowId: 1, i: 0, j: 0, value: 1, formula: 'sumChildren()', formulaDisabled: true, }, 100: { id: 100, rowId: 100, i: 1, j: 0, value: 200, error: null, formula: 'sumChildren()', formulaDisabled: false, type: 'text', }, 101: { id: 101, rowId: 101, i: 2, j: 0, value: 100, type: 'text' }, 102: { id: 102, rowId: 102, i: 3, j: 0, value: 100, type: 'text' }, }, treeContext: { '-1': { childrenIds: [1, 100], index: 0, level: 0, parentId: undefined, path: [], }, 1: { childrenIds: [], index: 0, level: 1, parentId: '-1', path: [0] }, 100: { childrenIds: [101, 102], index: 1, level: 1, parentId: '-1', path: [1] }, 101: { childrenIds: [], index: 0, level: 2, parentId: 100, path: [1, 0] }, 102: { childrenIds: [], index: 1, level: 2, parentId: 100, path: [1, 1] }, }, cellDeps: { 101: [100], 102: [100], }, varDeps: {}, }; expect(result).toEqual(expected); }); it('case1: 插入子树为child(可以容纳插入单行情形)', () => { const result = insertTreeRow( state, 'child', 0, rowsToInsert, undefined as any, undefined as any, undefined as any, ); const expected = { rows: [ { id: 1, level: 1, i: 0, type: 'body', cellIds: [1], }, { id: 100, level: 2, i: 1, type: 'body', cellIds: [100], }, { id: 101, level: 3, i: 2, type: 'body', cellIds: [101] }, { id: 102, level: 3, i: 3, type: 'body', cellIds: [102], }, ], cells: { 1: { id: 1, rowId: 1, i: 0, j: 0, value: 1, formula: 'sumChildren()', formulaDisabled: true, }, 100: { id: 100, rowId: 100, i: 1, j: 0, error: null, value: 200, formula: 'sumChildren()', formulaDisabled: false, // 注意100/101/102三个单元格是新插入的, 只能使用column.type type: 'text', }, 101: { id: 101, rowId: 101, i: 2, j: 0, value: 100, type: 'text' }, 102: { id: 102, rowId: 102, i: 3, j: 0, value: 100, type: 'text' }, }, treeContext: { '-1': { childrenIds: [1], index: 0, level: 0, parentId: undefined, path: [], }, 1: { childrenIds: [100], index: 0, level: 1, parentId: '-1', path: [0] }, 100: { childrenIds: [101, 102], index: 0, level: 2, parentId: 1, path: [0, 0] }, 101: { childrenIds: [], index: 0, level: 3, parentId: 100, path: [0, 0, 0] }, 102: { childrenIds: [], index: 1, level: 3, parentId: 100, path: [0, 0, 1] }, }, cellDeps: { 101: [100], 102: [100], }, varDeps: {}, }; expect(result).toEqual(expected); }); }); describe('deleteRow', () => { const rows: IRow[] = [ { id: 1, level: 1, i: 0, type: 'body', cellIds: [1] }, { id: 2, level: 2, i: 1, type: 'body', cellIds: [2] }, { id: 3, level: 3, i: 2, type: 'body', cellIds: [3] }, { id: 4, level: 1, i: 3, type: 'body', cellIds: [4] }, ]; const cells: ICell[] = [ { id: 1, rowId: 1, i: 0, j: 0, value: 1 }, { id: 2, rowId: 2, i: 1, j: 0, value: 1 }, { id: 3, rowId: 3, i: 2, j: 0, value: 1 }, { id: 4, rowId: 4, i: 3, j: 0, value: 1 }, ]; const state = ({ columns: [{ type: 'text' }], rows, cells: idMap(cells), treeContext: { 1: { childrenIds: [2], parentId: '-1' }, 2: { childrenIds: [3], parentId: 1 }, 3: { childrenIds: [4], parentId: 2 }, 4: { childrenIds: [], parentId: '-1' }, }, } as any) as IStoreState; console.warn('本方法假定参数是正常的, 因此不检查 0行等情形'); it('case0: 删除第1行', () => { const result = deleteTreeRow(state, 0, undefined as any, undefined as any); const expected = { rows: [{ id: 4, level: 1, i: 3, type: 'body', cellIds: [4] }], cells: idMap([{ id: 4, rowId: 4, i: 3, j: 0, value: 1 }]), treeContext: { '-1': { childrenIds: [4], index: 0, level: 0, parentId: undefined, path: [], }, 4: { index: 0, level: 1, path: [0], childrenIds: [], parentId: '-1' }, }, cellDeps: {}, varDeps: {}, }; expect(result).toEqual(expected); }); }); describe('pushRow', () => { const rows: IRow[] = [ { id: 1, level: 1, i: 0, type: 'body', cellIds: [1] }, { id: 2, level: 2, i: 1, type: 'body', cellIds: [2] }, { id: 3, level: 3, i: 2, type: 'body', cellIds: [3] }, { id: 4, level: 1, i: 3, type: 'body', cellIds: [4] }, ]; const cells: ICell[] = [ { id: 1, rowId: 1, i: 0, j: 0, value: 1 }, { id: 2, rowId: 2, i: 1, j: 0, value: 1 }, { id: 3, rowId: 3, i: 2, j: 0, value: 1 }, { id: 4, rowId: 4, i: 3, j: 0, value: 1 }, ]; const state = ({ columns: [{ type: 'text' }], rows, cells: idMap(cells), treeContext: { 1: { childrenIds: [2], parentId: '-1' }, 2: { childrenIds: [3], parentId: 1 }, 3: { childrenIds: [4], parentId: 2 }, 4: { childrenIds: [], parentId: '-1' }, }, } as any) as IStoreState; console.warn('本方法假定参数是正常的, 因此不检查 0行等情形'); it('case0: 第1行升级, 无效', () => { const result = pushTreeRow(state, 'left', 0, undefined as any, undefined as any); const expected = null; expect(result).toEqual(expected); }); it('case1: 第1行降级, 无效', () => { const result = pushTreeRow(state, 'right', 0, undefined as any, undefined as any); const expected = null; expect(result).toEqual(expected); }); it('case3: 第2行升级', () => { const result = pushTreeRow(state, 'left', 1, undefined as any, undefined as any); const expected = { rows: [ { id: 1, level: 1, i: 0, type: 'body', cellIds: [1] }, { id: 2, level: 1, i: 1, type: 'body', cellIds: [2] }, { id: 3, level: 2, i: 2, type: 'body', cellIds: [3] }, { id: 4, level: 1, i: 3, type: 'body', cellIds: [4] }, ], cells: idMap(cells), treeContext: { '-1': { childrenIds: [1, 2, 4], index: 0, level: 0, parentId: undefined, path: [], }, 1: { index: 0, level: 1, childrenIds: [], parentId: '-1', path: [0] }, 2: { index: 1, level: 1, childrenIds: [3], parentId: '-1', path: [1] }, 3: { index: 0, level: 2, childrenIds: [], parentId: 2, path: [1, 0] }, 4: { index: 2, level: 1, childrenIds: [], parentId: '-1', path: [2] }, }, cellDeps: {}, varDeps: {}, }; expect(result).toEqual(expected); }); it('case4: 第2行降级, 无效', () => { const result = pushTreeRow(state, 'right', 1, undefined as any, undefined as any); const expected = null; expect(result).toEqual(expected); }); }); describe('getInsertAtIndex', () => { const state = { rows: [ { id: 1, level: 1, i: 0 }, { id: 2, level: 2, i: 1 }, { id: 3, level: 2, i: 2 }, { id: 4, level: 1, i: 3 }, ], treeContext: { '-1': { level: 0, parentId: undefined, childrenIds: [1] }, 1: { level: 1, parentId: '-1', childrenIds: [2, 3] }, 2: { level: 2, parentId: 1 }, 3: { level: 2, parentId: 1 }, 4: { level: 1, parentId: '-1' }, }, } as any; it('case0: 插入sibling, 第1行', () => { const result = getInsertAtIndex(state, 'sibling', 0); expect(result).toBe(3); }); it('case1: 插入sibling, 第2行', () => { const result = getInsertAtIndex(state, 'sibling', 1); expect(result).toBe(2); }); it('case1: 插入child, 非一级', () => { expect(getInsertAtIndex(state, 'child', 0)).toBe(3); expect(getInsertAtIndex(state, 'child', 0, 0)).toBe(1); expect(getInsertAtIndex(state, 'child', 0, 1)).toBe(2); expect(getInsertAtIndex(state, 'child', 3)).toBe(4); expect(getInsertAtIndex(state, 'child', 3, 0)).toBe(4); }); it('case1: 插入child, 第-1行', () => { expect(getInsertAtIndex(state, 'child', -1)).toBe(4); expect(getInsertAtIndex(state, 'child', -1, 0)).toBe(0); }); }); /* describe('getNewRowDimensions', () => { // 这是移动前的 const rowDimensions = { 1: { height: 100, top: 0, offsetTop: 0, offsetHeight: 0 }, 2: { height: 100, top: 100, offsetTop: 0, offsetHeight: 0 }, 3: { height: 100, top: 200, offsetTop: 0, offsetHeight: 0 }, 4: { height: 100, top: 300, offsetTop: 0, offsetHeight: 0 }, }; it('case0: 下移行1', () => { expect(getNewRowDimensions([4, 1, 2, 3], rowDimensions)).toEqual({ 1: { height: 100, top: 100 }, 2: { height: 100, top: 200 }, 3: { height: 100, top: 300 }, 4: { height: 100, top: 0 }, }); }); }); */ /* 不再使用 describe('amendCellI', () => { it('case0', () => { // 移动后的rows const rows = [ { id: 1, i: 3, cellIds: [1] }, { id: 2, i: 0, cellIds: [2] }, { id: 3, i: 1, cellIds: [3] }, { id: 4, i: 2, cellIds: [4] }, ]; // 移动前的cells const cells = { 1: { rowId: 1, i: 0 }, 2: { rowId: 2, i: 1 }, 3: { rowId: 3, i: 2 }, 4: { rowId: 4, i: 3 }, }; const expected = { 1: { rowId: 1, i: 3 }, 2: { rowId: 2, i: 0 }, 3: { rowId: 3, i: 1 }, 4: { rowId: 4, i: 2 }, }; const result = amendCellI(rows, cells as any); expect(result).toEqual(expected); }); }); */ describe('inferHostRows', () => { const rows = [ { id: 1, i: 0, level: 1, cellIds: [1] }, // 1, sumChildren { id: 2, i: 1, level: 2, cellIds: [2] }, // 2, sumChildren { id: 3, i: 2, level: 3, cellIds: [3] }, // 3, leaf { id: 4, i: 3, level: 3, cellIds: [4] }, // 3, leaf { id: 5, i: 4, level: 3, cellIds: [5] }, // 3, leaf + sumSibling { id: 6, i: 5, level: 1, cellIds: [6] }, // 1, sumSibling ]; const cells = { 1: { rowId: 1, i: 0, j: 0 }, 2: { rowId: 2, i: 1, j: 0 }, 3: { rowId: 3, i: 2, j: 0 }, 4: { rowId: 4, i: 3, j: 0 }, 5: { rowId: 5, i: 4, j: 0 }, 6: { rowId: 6, i: 5, j: 0 }, }; const treeContext = { 1: { id: 1, parentId: '-1', childrenIds: [2] }, 2: { id: 2, parentId: 1, childrenIds: [3, 4, 5] }, 3: { id: 3, parentId: 2, childrenIds: [] }, 4: { id: 4, parentId: 2, childrenIds: [] }, 5: { id: 5, parentId: 2, childrenIds: [] }, 6: { id: 6, parentId: -1, childrenIds: [] }, }; const state = { rows, cells, treeContext, cellDeps: { 1: [6], 2: [1, 6], 3: [5, 2, 1, 6], 4: [5, 2, 1, 6], 5: [2, 1, 6], }, } as any; it('inferHostRowsByInsert', () => { expect(inferHostRowsByInsert(state, 0, [])).toEqual([1, 6]); expect(inferHostRowsByInsert(state, 1, [])).toEqual([5, 2, 1, 6]); expect(inferHostRowsByInsert(state, 2, [])).toEqual([3, 5, 2, 1, 6]); expect(inferHostRowsByInsert(state, 3, [])).toEqual([4, 5, 2, 1, 6]); expect(inferHostRowsByInsert(state, 4, [])).toEqual([5, 2, 1, 6]); expect(inferHostRowsByInsert(state, 5, [])).toEqual([6]); }); it('inferHostRowsByPush', () => { // 第3行升级, 第4 5 行变成3行下级 const stateAfterPush1 = { ...state, rows: [rows[0], rows[1], { ...rows[2], level: 2 }, rows[3], rows[4], rows[5]], }; expect(inferHostRowsByPush(state, stateAfterPush1, 2, 1)).toEqual([5, 2, 1, 6, 3, 4]); // 第4行升级 const stateAfterPush2 = { ...state, rows: [rows[0], rows[1], rows[2], { ...rows[3], level: 2 }, rows[4], rows[5]], }; expect(inferHostRowsByPush(state, stateAfterPush2, 3, 1)).toEqual([5, 2, 1, 6, 4]); // 第4行降级 const stateAfterPush3 = { ...state, rows: [rows[0], rows[1], rows[2], { ...rows[3], level: 4 }, rows[4], rows[5]], }; expect(inferHostRowsByPush(state, stateAfterPush3, 3, 3)).toEqual([5, 2, 1, 6, 4, 3]); // 第5行升级 const stateAfterPush4 = { ...state, rows: [rows[0], rows[1], rows[2], rows[3], { ...rows[4], level: 2 }, rows[5]], }; expect(inferHostRowsByPush(state, stateAfterPush4, 4, 1)).toEqual([2, 1, 6, 5]); // 第5行降级 const stateAfterPush5 = { ...state, rows: [rows[0], rows[1], rows[2], rows[3], { ...rows[4], level: 4 }, rows[5]], }; expect(inferHostRowsByPush(state, stateAfterPush5, 4, 4)).toEqual([2, 1, 6, 5, 4]); // // 第6行降级 const stateAfterPush6 = { ...state, rows: [rows[0], rows[1], rows[2], rows[3], rows[4], { ...rows[5], level: 2 }], }; expect(inferHostRowsByPush(state, stateAfterPush6, 5, 1)).toEqual([6, 1]); }); });