From 3325c3946d0ab77083555bab334381a1167ee580 Mon Sep 17 00:00:00 2001 From: Dokiy <49900744+Dokiys@users.noreply.github.com> Date: Mon, 6 Dec 2021 22:37:25 +0800 Subject: [PATCH] Fix adjustMergeCellsHelper and add some test cases (#1082) Signed-off-by: Dokiys --- adjust.go | 42 +++++++--- adjust_test.go | 207 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 233 insertions(+), 16 deletions(-) diff --git a/adjust.go b/adjust.go index 9f2176f..243c774 100644 --- a/adjust.go +++ b/adjust.go @@ -208,20 +208,23 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off if y1 == num && y2 == num && offset < 0 { f.deleteMergeCell(ws, i) i-- + continue } - y1 = f.adjustMergeCellsHelper(y1, num, offset) - y2 = f.adjustMergeCellsHelper(y2, num, offset) + + y1, y2 = f.adjustMergeCellsHelper(y1, y2, num, offset) } else { if x1 == num && x2 == num && offset < 0 { f.deleteMergeCell(ws, i) i-- + continue } - x1 = f.adjustMergeCellsHelper(x1, num, offset) - x2 = f.adjustMergeCellsHelper(x2, num, offset) + + x1, x2 = f.adjustMergeCellsHelper(x1, x2, num, offset) } - if x1 == x2 && y1 == y2 && i >= 0 { + if x1 == x2 && y1 == y2 { f.deleteMergeCell(ws, i) i-- + continue } if areaData.Ref, err = f.coordinatesToAreaRef([]int{x1, y1, x2, y2}); err != nil { return err @@ -233,19 +236,34 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off // adjustMergeCellsHelper provides a function for adjusting merge cells to // compare and calculate cell axis by the given pivot, operation axis and // offset. -func (f *File) adjustMergeCellsHelper(pivot, num, offset int) int { - if pivot > num { - pivot += offset - if pivot < 1 { - return 1 +func (f *File) adjustMergeCellsHelper(p1, p2, num, offset int) (int, int) { + if p2 < p1 { + p1, p2 = p2, p1 + } + + if offset >= 0 { + if num <= p1 { + p1 += offset + p2 += offset + } else if num <= p2 { + p2 += offset } - return pivot + return p1, p2 + } + if num < p1 || (num == p1 && num == p2) { + p1 += offset + p2 += offset + } else if num <= p2 { + p2 += offset } - return pivot + return p1, p2 } // deleteMergeCell provides a function to delete merged cell by given index. func (f *File) deleteMergeCell(ws *xlsxWorksheet, idx int) { + if idx < 0 { + return + } if len(ws.MergeCells.Cells) > idx { ws.MergeCells.Cells = append(ws.MergeCells.Cells[:idx], ws.MergeCells.Cells[idx+1:]...) ws.MergeCells.Count = len(ws.MergeCells.Cells) diff --git a/adjust_test.go b/adjust_test.go index f56f763..3509b5d 100644 --- a/adjust_test.go +++ b/adjust_test.go @@ -45,6 +45,209 @@ func TestAdjustMergeCells(t *testing.T) { }, }, }, columns, 1, -1)) + + // testing adjustMergeCells + var cases []struct { + lable string + ws *xlsxWorksheet + dir adjustDirection + num int + offset int + expect string + } + + // testing insert + cases = []struct { + lable string + ws *xlsxWorksheet + dir adjustDirection + num int + offset int + expect string + }{ + { + lable: "insert row on ref", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: rows, + num: 2, + offset: 1, + expect: "A3:B4", + }, + { + lable: "insert row on bottom of ref", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: rows, + num: 3, + offset: 1, + expect: "A2:B4", + }, + { + lable: "insert column on the left", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: columns, + num: 1, + offset: 1, + expect: "B2:C3", + }, + } + for _, c := range cases { + assert.NoError(t, f.adjustMergeCells(c.ws, c.dir, c.num, 1)) + assert.Equal(t, c.expect, c.ws.MergeCells.Cells[0].Ref, c.lable) + } + + // testing delete + cases = []struct { + lable string + ws *xlsxWorksheet + dir adjustDirection + num int + offset int + expect string + }{ + { + lable: "delete row on top of ref", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: rows, + num: 2, + offset: -1, + expect: "A2:B2", + }, + { + lable: "delete row on bottom of ref", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: rows, + num: 3, + offset: -1, + expect: "A2:B2", + }, + { + lable: "delete column on the ref left", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: columns, + num: 1, + offset: -1, + expect: "A2:A3", + }, + { + lable: "delete column on the ref right", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A2:B3", + }, + }, + }, + }, + dir: columns, + num: 2, + offset: -1, + expect: "A2:A3", + }, + } + for _, c := range cases { + assert.NoError(t, f.adjustMergeCells(c.ws, c.dir, c.num, -1)) + assert.Equal(t, c.expect, c.ws.MergeCells.Cells[0].Ref, c.lable) + } + + // testing delete one row/column + cases = []struct { + lable string + ws *xlsxWorksheet + dir adjustDirection + num int + offset int + expect string + }{ + { + lable: "delete one row ref", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A1:B1", + }, + }, + }, + }, + dir: rows, + num: 1, + offset: -1, + }, + { + lable: "delete one column ref", + ws: &xlsxWorksheet{ + MergeCells: &xlsxMergeCells{ + Cells: []*xlsxMergeCell{ + { + Ref: "A1:A2", + }, + }, + }, + }, + dir: columns, + num: 1, + offset: -1, + }, + } + for _, c := range cases { + assert.NoError(t, f.adjustMergeCells(c.ws, c.dir, c.num, -1)) + assert.Equal(t, 0, len(c.ws.MergeCells.Cells), c.lable) + } + + f = NewFile() + p1, p2 := f.adjustMergeCellsHelper(2, 1, 0, 0) + assert.Equal(t, 1, p1) + assert.Equal(t, 2, p2) + f.deleteMergeCell(nil, -1) } func TestAdjustAutoFilter(t *testing.T) { @@ -84,10 +287,6 @@ func TestAdjustHelper(t *testing.T) { assert.EqualError(t, f.adjustHelper("SheetN", rows, 0, 0), "sheet SheetN is not exist") } -func TestAdjustMergeCellsHelper(t *testing.T) { - assert.Equal(t, 1, NewFile().adjustMergeCellsHelper(1, 0, -2)) -} - func TestAdjustCalcChain(t *testing.T) { f := NewFile() f.CalcChain = &xlsxCalcChain{