2018-01-19 17:32:54 +08:00
|
|
|
package excelize
|
|
|
|
|
2018-12-27 18:51:44 +08:00
|
|
|
import (
|
2021-09-18 23:20:24 +08:00
|
|
|
"archive/zip"
|
|
|
|
"bytes"
|
2020-07-20 00:05:37 +08:00
|
|
|
"encoding/xml"
|
2018-12-27 18:51:44 +08:00
|
|
|
"fmt"
|
2021-11-13 14:11:16 +08:00
|
|
|
"io"
|
2021-09-18 23:20:24 +08:00
|
|
|
"os"
|
2022-08-12 00:32:51 +08:00
|
|
|
"runtime"
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2021-09-18 23:20:24 +08:00
|
|
|
"sync"
|
2018-12-27 18:51:44 +08:00
|
|
|
"testing"
|
2018-01-19 17:32:54 +08:00
|
|
|
|
2018-12-27 18:51:44 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
2021-09-18 23:20:24 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-12-27 18:51:44 +08:00
|
|
|
)
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
var validColumns = []struct {
|
|
|
|
Name string
|
|
|
|
Num int
|
|
|
|
}{
|
|
|
|
{Name: "A", Num: 1},
|
|
|
|
{Name: "Z", Num: 26},
|
|
|
|
{Name: "AA", Num: 26 + 1},
|
|
|
|
{Name: "AK", Num: 26 + 11},
|
|
|
|
{Name: "ak", Num: 26 + 11},
|
|
|
|
{Name: "Ak", Num: 26 + 11},
|
|
|
|
{Name: "aK", Num: 26 + 11},
|
|
|
|
{Name: "AZ", Num: 26 + 26},
|
|
|
|
{Name: "ZZ", Num: 26 + 26*26},
|
|
|
|
{Name: "AAA", Num: 26 + 26*26 + 1},
|
|
|
|
}
|
|
|
|
|
|
|
|
var invalidColumns = []struct {
|
|
|
|
Name string
|
|
|
|
Num int
|
|
|
|
}{
|
|
|
|
{Name: "", Num: -1},
|
|
|
|
{Name: " ", Num: -1},
|
|
|
|
{Name: "_", Num: -1},
|
|
|
|
{Name: "__", Num: -1},
|
|
|
|
{Name: "-1", Num: -1},
|
|
|
|
{Name: "0", Num: -1},
|
|
|
|
{Name: " A", Num: -1},
|
|
|
|
{Name: "A ", Num: -1},
|
|
|
|
{Name: "A1", Num: -1},
|
|
|
|
{Name: "1A", Num: -1},
|
|
|
|
{Name: " a", Num: -1},
|
|
|
|
{Name: "a ", Num: -1},
|
|
|
|
{Name: "a1", Num: -1},
|
|
|
|
{Name: "1a", Num: -1},
|
|
|
|
{Name: " _", Num: -1},
|
|
|
|
{Name: "_ ", Num: -1},
|
|
|
|
{Name: "_1", Num: -1},
|
|
|
|
{Name: "1_", Num: -1},
|
|
|
|
}
|
|
|
|
|
|
|
|
var invalidCells = []string{"", "A", "AA", " A", "A ", "1A", "A1A", "A1 ", " A1", "1A1", "a-1", "A-1"}
|
|
|
|
|
|
|
|
var invalidIndexes = []int{-100, -2, -1, 0}
|
|
|
|
|
|
|
|
func TestColumnNameToNumber_OK(t *testing.T) {
|
|
|
|
const msg = "Column %q"
|
|
|
|
for _, col := range validColumns {
|
|
|
|
out, err := ColumnNameToNumber(col.Name)
|
|
|
|
if assert.NoErrorf(t, err, msg, col.Name) {
|
|
|
|
assert.Equalf(t, col.Num, out, msg, col.Name)
|
|
|
|
}
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestColumnNameToNumber_Error(t *testing.T) {
|
|
|
|
const msg = "Column %q"
|
|
|
|
for _, col := range invalidColumns {
|
|
|
|
out, err := ColumnNameToNumber(col.Name)
|
|
|
|
if assert.Errorf(t, err, msg, col.Name) {
|
|
|
|
assert.Equalf(t, col.Num, out, msg, col.Name)
|
|
|
|
}
|
|
|
|
}
|
2020-05-29 00:26:40 +08:00
|
|
|
_, err := ColumnNameToNumber("XFE")
|
2022-07-14 23:36:43 +08:00
|
|
|
assert.ErrorIs(t, err, ErrColumnNumber)
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
2018-01-19 17:32:54 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
func TestColumnNumberToName_OK(t *testing.T) {
|
|
|
|
const msg = "Column %q"
|
|
|
|
for _, col := range validColumns {
|
|
|
|
out, err := ColumnNumberToName(col.Num)
|
|
|
|
if assert.NoErrorf(t, err, msg, col.Name) {
|
|
|
|
assert.Equalf(t, strings.ToUpper(col.Name), out, msg, col.Name)
|
|
|
|
}
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
2018-12-27 18:51:44 +08:00
|
|
|
}
|
2018-01-19 17:32:54 +08:00
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
func TestColumnNumberToName_Error(t *testing.T) {
|
|
|
|
out, err := ColumnNumberToName(-1)
|
|
|
|
if assert.Error(t, err) {
|
|
|
|
assert.Equal(t, "", out)
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
out, err = ColumnNumberToName(0)
|
|
|
|
if assert.Error(t, err) {
|
|
|
|
assert.Equal(t, "", out)
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
2020-07-11 02:31:02 +08:00
|
|
|
|
2022-07-14 23:36:43 +08:00
|
|
|
_, err = ColumnNumberToName(MaxColumns + 1)
|
|
|
|
assert.ErrorIs(t, err, ErrColumnNumber)
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
func TestSplitCellName_OK(t *testing.T) {
|
|
|
|
const msg = "Cell \"%s%d\""
|
|
|
|
for i, col := range validColumns {
|
|
|
|
row := i + 1
|
|
|
|
c, r, err := SplitCellName(col.Name + strconv.Itoa(row))
|
|
|
|
if assert.NoErrorf(t, err, msg, col.Name, row) {
|
|
|
|
assert.Equalf(t, col.Name, c, msg, col.Name, row)
|
|
|
|
assert.Equalf(t, row, r, msg, col.Name, row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSplitCellName_Error(t *testing.T) {
|
|
|
|
const msg = "Cell %q"
|
|
|
|
for _, cell := range invalidCells {
|
|
|
|
c, r, err := SplitCellName(cell)
|
|
|
|
if assert.Errorf(t, err, msg, cell) {
|
|
|
|
assert.Equalf(t, "", c, msg, cell)
|
|
|
|
assert.Equalf(t, -1, r, msg, cell)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestJoinCellName_OK(t *testing.T) {
|
|
|
|
const msg = "Cell \"%s%d\""
|
|
|
|
|
|
|
|
for i, col := range validColumns {
|
|
|
|
row := i + 1
|
|
|
|
cell, err := JoinCellName(col.Name, row)
|
|
|
|
if assert.NoErrorf(t, err, msg, col.Name, row) {
|
|
|
|
assert.Equalf(t, strings.ToUpper(fmt.Sprintf("%s%d", col.Name, row)), cell, msg, row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestJoinCellName_Error(t *testing.T) {
|
|
|
|
const msg = "Cell \"%s%d\""
|
|
|
|
|
|
|
|
test := func(col string, row int) {
|
|
|
|
cell, err := JoinCellName(col, row)
|
|
|
|
if assert.Errorf(t, err, msg, col, row) {
|
|
|
|
assert.Equalf(t, "", cell, msg, col, row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, col := range invalidColumns {
|
|
|
|
test(col.Name, 1)
|
|
|
|
for _, row := range invalidIndexes {
|
|
|
|
test("A", row)
|
|
|
|
test(col.Name, row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCellNameToCoordinates_OK(t *testing.T) {
|
|
|
|
const msg = "Cell \"%s%d\""
|
|
|
|
for i, col := range validColumns {
|
|
|
|
row := i + 1
|
|
|
|
c, r, err := CellNameToCoordinates(col.Name + strconv.Itoa(row))
|
|
|
|
if assert.NoErrorf(t, err, msg, col.Name, row) {
|
|
|
|
assert.Equalf(t, col.Num, c, msg, col.Name, row)
|
|
|
|
assert.Equalf(t, i+1, r, msg, col.Name, row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCellNameToCoordinates_Error(t *testing.T) {
|
|
|
|
const msg = "Cell %q"
|
|
|
|
for _, cell := range invalidCells {
|
|
|
|
c, r, err := CellNameToCoordinates(cell)
|
|
|
|
if assert.Errorf(t, err, msg, cell) {
|
|
|
|
assert.Equalf(t, -1, c, msg, cell)
|
|
|
|
assert.Equalf(t, -1, r, msg, cell)
|
|
|
|
}
|
|
|
|
}
|
2020-05-29 00:26:40 +08:00
|
|
|
_, _, err := CellNameToCoordinates("A1048577")
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, err, ErrMaxRows.Error())
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestCoordinatesToCellName_OK(t *testing.T) {
|
|
|
|
const msg = "Coordinates [%d, %d]"
|
|
|
|
for i, col := range validColumns {
|
|
|
|
row := i + 1
|
|
|
|
cell, err := CoordinatesToCellName(col.Num, row)
|
|
|
|
if assert.NoErrorf(t, err, msg, col.Num, row) {
|
|
|
|
assert.Equalf(t, strings.ToUpper(col.Name+strconv.Itoa(row)), cell, msg, col.Num, row)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCoordinatesToCellName_Error(t *testing.T) {
|
|
|
|
const msg = "Coordinates [%d, %d]"
|
|
|
|
|
|
|
|
test := func(col, row int) {
|
|
|
|
cell, err := CoordinatesToCellName(col, row)
|
|
|
|
if assert.Errorf(t, err, msg, col, row) {
|
|
|
|
assert.Equalf(t, "", cell, msg, col, row)
|
|
|
|
}
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
|
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
|
|
|
for _, col := range invalidIndexes {
|
|
|
|
test(col, 1)
|
|
|
|
for _, row := range invalidIndexes {
|
|
|
|
test(1, row)
|
|
|
|
test(col, row)
|
|
|
|
}
|
2018-01-19 17:32:54 +08:00
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:41:14 +08:00
|
|
|
|
2022-09-28 00:04:17 +08:00
|
|
|
func TestCoordinatesToRangeRef(t *testing.T) {
|
2021-08-06 22:44:43 +08:00
|
|
|
f := NewFile()
|
2022-09-28 00:04:17 +08:00
|
|
|
_, err := f.coordinatesToRangeRef([]int{})
|
2021-08-06 22:44:43 +08:00
|
|
|
assert.EqualError(t, err, ErrCoordinates.Error())
|
2022-09-28 00:04:17 +08:00
|
|
|
_, err = f.coordinatesToRangeRef([]int{1, -1, 1, 1})
|
2022-09-18 00:07:15 +08:00
|
|
|
assert.EqualError(t, err, "invalid cell reference [1, -1]")
|
2022-09-28 00:04:17 +08:00
|
|
|
_, err = f.coordinatesToRangeRef([]int{1, 1, 1, -1})
|
2022-09-18 00:07:15 +08:00
|
|
|
assert.EqualError(t, err, "invalid cell reference [1, -1]")
|
2022-09-28 00:04:17 +08:00
|
|
|
ref, err := f.coordinatesToRangeRef([]int{1, 1, 1, 1})
|
2021-08-06 22:44:43 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.EqualValues(t, ref, "A1:A1")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSortCoordinates(t *testing.T) {
|
|
|
|
assert.EqualError(t, sortCoordinates(make([]int, 3)), ErrCoordinates.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInStrSlice(t *testing.T) {
|
2022-02-13 00:06:30 +08:00
|
|
|
assert.EqualValues(t, -1, inStrSlice([]string{}, "", true))
|
2021-08-06 22:44:43 +08:00
|
|
|
}
|
|
|
|
|
2023-08-24 23:51:07 +08:00
|
|
|
func TestAttrValue(t *testing.T) {
|
|
|
|
assert.Empty(t, (&attrValString{}).Value())
|
|
|
|
assert.False(t, (&attrValBool{}).Value())
|
|
|
|
assert.Zero(t, (&attrValFloat{}).Value())
|
|
|
|
}
|
|
|
|
|
2021-11-13 14:11:16 +08:00
|
|
|
func TestBoolValMarshal(t *testing.T) {
|
|
|
|
bold := true
|
|
|
|
node := &xlsxFont{B: &attrValBool{Val: &bold}}
|
|
|
|
data, err := xml.Marshal(node)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, `<xlsxFont><b val="1"></b></xlsxFont>`, string(data))
|
|
|
|
|
|
|
|
node = &xlsxFont{}
|
|
|
|
err = xml.Unmarshal(data, node)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NotEqual(t, nil, node)
|
|
|
|
assert.NotEqual(t, nil, node.B)
|
|
|
|
assert.NotEqual(t, nil, node.B.Val)
|
|
|
|
assert.Equal(t, true, *node.B.Val)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBoolValUnmarshalXML(t *testing.T) {
|
|
|
|
node := xlsxFont{}
|
|
|
|
assert.NoError(t, xml.Unmarshal([]byte("<xlsxFont><b val=\"\"></b></xlsxFont>"), &node))
|
|
|
|
assert.Equal(t, true, *node.B.Val)
|
|
|
|
for content, err := range map[string]string{
|
|
|
|
"<xlsxFont><b val=\"0\"><i></i></b></xlsxFont>": "unexpected child of attrValBool",
|
|
|
|
"<xlsxFont><b val=\"x\"></b></xlsxFont>": "strconv.ParseBool: parsing \"x\": invalid syntax",
|
|
|
|
} {
|
|
|
|
assert.EqualError(t, xml.Unmarshal([]byte(content), &node), err)
|
|
|
|
}
|
|
|
|
attr := attrValBool{}
|
|
|
|
assert.EqualError(t, attr.UnmarshalXML(xml.NewDecoder(strings.NewReader("")), xml.StartElement{}), io.EOF.Error())
|
|
|
|
}
|
|
|
|
|
2023-09-16 12:21:11 +08:00
|
|
|
func TestExtUnmarshalXML(t *testing.T) {
|
|
|
|
f, extLst := NewFile(), decodeExtLst{}
|
|
|
|
expected := fmt.Sprintf(`<extLst><ext uri="%s" xmlns:x14="%s"/></extLst>`,
|
|
|
|
ExtURISlicerCachesX14, NameSpaceSpreadSheetX14.Value)
|
|
|
|
assert.NoError(t, f.xmlNewDecoder(strings.NewReader(expected)).Decode(&extLst))
|
|
|
|
assert.Len(t, extLst.Ext, 1)
|
|
|
|
assert.Equal(t, extLst.Ext[0].URI, ExtURISlicerCachesX14)
|
|
|
|
}
|
|
|
|
|
2020-04-02 00:41:14 +08:00
|
|
|
func TestBytesReplace(t *testing.T) {
|
|
|
|
s := []byte{0x01}
|
|
|
|
assert.EqualValues(t, s, bytesReplace(s, []byte{}, []byte{}, 0))
|
|
|
|
}
|
2020-05-23 13:29:51 +08:00
|
|
|
|
2021-08-09 22:22:43 +08:00
|
|
|
func TestGetRootElement(t *testing.T) {
|
2023-03-25 13:30:13 +08:00
|
|
|
assert.Len(t, getRootElement(xml.NewDecoder(strings.NewReader(""))), 0)
|
2021-08-09 22:22:43 +08:00
|
|
|
}
|
|
|
|
|
2020-07-20 00:05:37 +08:00
|
|
|
func TestSetIgnorableNameSpace(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
f.xmlAttr["xml_path"] = []xml.Attr{{}}
|
|
|
|
f.setIgnorableNameSpace("xml_path", 0, xml.Attr{Name: xml.Name{Local: "c14"}})
|
|
|
|
assert.EqualValues(t, "c14", f.xmlAttr["xml_path"][0].Value)
|
|
|
|
}
|
|
|
|
|
2020-05-23 13:29:51 +08:00
|
|
|
func TestStack(t *testing.T) {
|
|
|
|
s := NewStack()
|
|
|
|
assert.Equal(t, s.Peek(), nil)
|
|
|
|
assert.Equal(t, s.Pop(), nil)
|
|
|
|
}
|
2021-04-30 00:14:42 +08:00
|
|
|
|
|
|
|
func TestGenXMLNamespace(t *testing.T) {
|
|
|
|
assert.Equal(t, genXMLNamespace([]xml.Attr{
|
|
|
|
{Name: xml.Name{Space: NameSpaceXML, Local: "space"}, Value: "preserve"},
|
|
|
|
}), `xml:space="preserve">`)
|
|
|
|
}
|
2021-06-11 22:48:37 +08:00
|
|
|
|
|
|
|
func TestBstrUnmarshal(t *testing.T) {
|
|
|
|
bstrs := map[string]string{
|
|
|
|
"*": "*",
|
2021-08-28 09:23:44 +08:00
|
|
|
"*_x0000_": "*\x00",
|
|
|
|
"*_x0008_": "*\b",
|
|
|
|
"_x0008_*": "\b*",
|
|
|
|
"*_x0008_*": "*\b*",
|
2021-06-12 08:49:18 +08:00
|
|
|
"*_x4F60__x597D_": "*你好",
|
2021-06-13 11:23:52 +08:00
|
|
|
"*_xG000_": "*_xG000_",
|
2022-12-07 00:45:27 +08:00
|
|
|
"*_xG05F_x0001_*": "*_xG05F\x01*",
|
2021-08-28 09:23:44 +08:00
|
|
|
"*_x005F__x0008_*": "*_\b*",
|
2021-06-11 22:48:37 +08:00
|
|
|
"*_x005F_x0001_*": "*_x0001_*",
|
2021-08-28 09:23:44 +08:00
|
|
|
"*_x005f_x005F__x0008_*": "*_x005F_\b*",
|
2022-12-07 00:45:27 +08:00
|
|
|
"*_x005F_x005F_xG05F_x0006_*": "*_x005F_xG05F\x06*",
|
2021-06-11 22:48:37 +08:00
|
|
|
"*_x005F_x005F_x005F_x0006_*": "*_x005F_x0006_*",
|
2021-08-28 09:23:44 +08:00
|
|
|
"_x005F__x0008_******": "_\b******",
|
|
|
|
"******_x005F__x0008_": "******_\b",
|
|
|
|
"******_x005F__x0008_******": "******_\b******",
|
2022-12-07 00:45:27 +08:00
|
|
|
"_x000x_x005F_x000x_": "_x000x_x000x_",
|
2021-06-11 22:48:37 +08:00
|
|
|
}
|
|
|
|
for bstr, expected := range bstrs {
|
2022-12-07 00:45:27 +08:00
|
|
|
assert.Equal(t, expected, bstrUnmarshal(bstr), bstr)
|
2021-06-11 22:48:37 +08:00
|
|
|
}
|
|
|
|
}
|
2021-06-16 23:03:50 +08:00
|
|
|
|
|
|
|
func TestBstrMarshal(t *testing.T) {
|
|
|
|
bstrs := map[string]string{
|
|
|
|
"*_xG05F_*": "*_xG05F_*",
|
|
|
|
"*_x0008_*": "*_x005F_x0008_*",
|
|
|
|
"*_x005F_*": "*_x005F_x005F_*",
|
|
|
|
"*_x005F_xG006_*": "*_x005F_x005F_xG006_*",
|
|
|
|
"*_x005F_x0006_*": "*_x005F_x005F_x005F_x0006_*",
|
|
|
|
}
|
|
|
|
for bstr, expected := range bstrs {
|
|
|
|
assert.Equal(t, expected, bstrMarshal(bstr))
|
|
|
|
}
|
|
|
|
}
|
2021-09-18 23:20:24 +08:00
|
|
|
|
|
|
|
func TestReadBytes(t *testing.T) {
|
|
|
|
f := &File{tempFiles: sync.Map{}}
|
|
|
|
sheet := "xl/worksheets/sheet1.xml"
|
|
|
|
f.tempFiles.Store(sheet, "/d/")
|
|
|
|
assert.Equal(t, []byte{}, f.readBytes(sheet))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnzipToTemp(t *testing.T) {
|
2023-06-30 13:02:18 +08:00
|
|
|
if ver := runtime.Version(); strings.HasPrefix(ver, "go1.19") || strings.HasPrefix(ver, "go1.2") {
|
|
|
|
t.Skip()
|
2022-08-12 00:32:51 +08:00
|
|
|
}
|
2021-09-18 23:20:24 +08:00
|
|
|
os.Setenv("TMPDIR", "test")
|
|
|
|
defer os.Unsetenv("TMPDIR")
|
2022-03-19 00:05:47 +08:00
|
|
|
assert.NoError(t, os.Chmod(os.TempDir(), 0o444))
|
2021-09-18 23:20:24 +08:00
|
|
|
f := NewFile()
|
|
|
|
data := []byte("PK\x03\x040000000PK\x01\x0200000" +
|
|
|
|
"0000000000000000000\x00" +
|
|
|
|
"\x00\x00\x00\x00\x00000000000000PK\x01" +
|
|
|
|
"\x020000000000000000000" +
|
|
|
|
"00000\v\x00\x00\x00\x00\x00000000000" +
|
|
|
|
"00000000000000PK\x01\x0200" +
|
|
|
|
"00000000000000000000" +
|
|
|
|
"00\v\x00\x00\x00\x00\x00000000000000" +
|
|
|
|
"00000000000PK\x01\x020000<" +
|
|
|
|
"0\x00\x0000000000000000\v\x00\v" +
|
|
|
|
"\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
|
|
|
|
"00000000PK\x01\x0200000000" +
|
|
|
|
"0000000000000000\v\x00\x00\x00" +
|
|
|
|
"\x00\x0000PK\x05\x06000000\x05\x000000" +
|
|
|
|
"\v\x00\x00\x00\x00\x00")
|
|
|
|
z, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = f.unzipToTemp(z.File[0])
|
|
|
|
require.Error(t, err)
|
2022-03-19 00:05:47 +08:00
|
|
|
assert.NoError(t, os.Chmod(os.TempDir(), 0o755))
|
2021-09-18 23:20:24 +08:00
|
|
|
|
|
|
|
_, err = f.unzipToTemp(z.File[0])
|
|
|
|
assert.EqualError(t, err, "EOF")
|
|
|
|
}
|