2018-01-19 17:32:54 +08:00
|
|
|
package excelize
|
|
|
|
|
2018-12-27 18:51:44 +08:00
|
|
|
import (
|
2020-07-20 00:05:37 +08:00
|
|
|
"encoding/xml"
|
2018-12-27 18:51:44 +08:00
|
|
|
"fmt"
|
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"
|
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"
|
|
|
|
)
|
|
|
|
|
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")
|
|
|
|
assert.EqualError(t, err, "column number exceeds maximum limit")
|
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
|
|
|
|
|
|
|
_, err = ColumnNumberToName(TotalColumns + 1)
|
|
|
|
assert.EqualError(t, err, "column number exceeds maximum limit")
|
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")
|
|
|
|
assert.EqualError(t, err, "row number exceeds maximum limit")
|
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
|
|
|
|
|
|
|
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
|
|
|
|
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">`)
|
|
|
|
}
|