Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix up tests
  • Loading branch information
tealeg committed Apr 26, 2020
1 parent 040da08 commit f860f36
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 108 deletions.
121 changes: 66 additions & 55 deletions file_test.go
Expand Up @@ -61,6 +61,52 @@ func TestFile(t *testing.T) {
c.Assert(xlsxFile, qt.Not(qt.IsNil))
})

csRunO(c, "TestFileWithEmptyCols", func(c *qt.C, option FileOption) {
f, err := OpenFile("./testdocs/empty_rows.xlsx", option)
c.Assert(err, qt.IsNil)
sheet, ok := f.Sheet["EmptyCols"]
c.Assert(ok, qt.Equals, true)

cell, err := sheet.Cell(0, 0)
c.Assert(err, qt.Equals, nil)
if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "")
}
cell, err = sheet.Cell(0, 2)
c.Assert(err, qt.Equals, nil)

if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "C1")
}
})

csRunO(c, "TestFileWithEmptyCols", func(c *qt.C, option FileOption) {
f, err := OpenFile("./testdocs/empty_rows.xlsx", option)
c.Assert(err, qt.IsNil)
sheet, ok := f.Sheet["EmptyCols"]
c.Assert(ok, qt.Equals, true)

cell, err := sheet.Cell(0, 0)
c.Assert(err, qt.Equals, nil)
if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "")
}
cell, err = sheet.Cell(0, 2)
c.Assert(err, qt.Equals, nil)

if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "C1")
}
})

csRunO(c, "TestPartialReadsWithFewSharedStringsOnlyPartiallyReads", func(c *qt.C, option FileOption) {
// This test verifies that a large file is only partially read when using a small row limit.
// This file is 11,228,530 bytes, but only 14,020 bytes get read out when using a row limit of 10.
Expand Down Expand Up @@ -1034,6 +1080,19 @@ func TestGetStyleFromZipFile(t *testing.T) {
func TestSliceReader(t *testing.T) {
c := qt.New(t)

fileToSliceCheckOutput := func(c *qt.C, output [][][]string) {
c.Assert(len(output), qt.Equals, 3)
c.Assert(len(output[0]), qt.Equals, 2)
c.Assert(len(output[0][0]), qt.Equals, 2)
c.Assert(output[0][0][0], qt.Equals, "Foo")
c.Assert(output[0][0][1], qt.Equals, "Bar")
c.Assert(len(output[0][1]), qt.Equals, 2)
c.Assert(output[0][1][0], qt.Equals, "Baz")
c.Assert(output[0][1][1], qt.Equals, "Quuk")
c.Assert(len(output[1]), qt.Equals, 0)
c.Assert(len(output[2]), qt.Equals, 0)
}

csRunO(c, "TestFileToSlice", func(c *qt.C, option FileOption) {
output, err := FileToSlice("./testdocs/testfile.xlsx", option)
c.Assert(err, qt.IsNil)
Expand Down Expand Up @@ -1068,63 +1127,15 @@ func TestSliceReader(t *testing.T) {
c.Assert(output[0][2][0], qt.Equals, "01.01.2016")
})

csRunO(c, "TestFileWithEmptyRows", func(c *qt.C, option FileOption) {
f, err := OpenFile("./testdocs/empty_rows.xlsx", option)
c.Assert(err, qt.IsNil)
sheet, ok := f.Sheet["EmptyRows"]
c.Assert(ok, qt.Equals, true)

cell, err := sheet.Cell(0, 0)
c.Assert(err, qt.Equals, nil)
if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "")
}
cell, err = sheet.Cell(2, 0)
c.Assert(err, qt.Equals, nil)

if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "A3")
}
})

csRunO(c, "TestFileWithEmptyCols", func(c *qt.C, option FileOption) {
f, err := OpenFile("./testdocs/empty_rows.xlsx", option)
c.Assert(err, qt.IsNil)
sheet, ok := f.Sheet["EmptyCols"]
c.Assert(ok, qt.Equals, true)

cell, err := sheet.Cell(0, 0)
c.Assert(err, qt.Equals, nil)
if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "")
}
cell, err = sheet.Cell(0, 2)
csRunO(c, "TestFileToSliceEmptyCells", func(c *qt.C, option FileOption) {
output, err := FileToSlice("./testdocs/empty_cells.xlsx", option)
c.Assert(err, qt.Equals, nil)

if val, err := cell.FormattedValue(); err != nil {
c.Error(err)
} else {
c.Assert(val, qt.Equals, "C1")
c.Assert(output, qt.HasLen, 1)
sheetSlice := output[0]
c.Assert(sheetSlice, qt.HasLen, 4)
for _, rowSlice := range sheetSlice {
c.Assert(rowSlice, qt.HasLen, 4)
}
})

}

func fileToSliceCheckOutput(c *qt.C, output [][][]string) {
c.Assert(len(output), qt.Equals, 3)
c.Assert(len(output[0]), qt.Equals, 2)
c.Assert(len(output[0][0]), qt.Equals, 2)
c.Assert(output[0][0][0], qt.Equals, "Foo")
c.Assert(output[0][0][1], qt.Equals, "Bar")
c.Assert(len(output[0][1]), qt.Equals, 2)
c.Assert(output[0][1][0], qt.Equals, "Baz")
c.Assert(output[0][1][1], qt.Equals, "Quuk")
c.Assert(len(output[1]), qt.Equals, 0)
c.Assert(len(output[2]), qt.Equals, 0)
}
58 changes: 49 additions & 9 deletions row.go
Expand Up @@ -99,23 +99,63 @@ func (r *Row) GetCell(colIdx int) *Cell {
return cell
}

// cellVisitorFlags contains flags that can be set by CellVisitorOption implementations to modify the behaviour of ForEachCell
type cellVisitorFlags struct {
// skipEmptyCells indicates if we should skip nil cells.
skipEmptyCells bool
}

// CellVisitorOption describes a function that can set values in a
// cellVisitorFlags struct to affect the way ForEachCell operates
type CellVisitorOption func(flags *cellVisitorFlags)

// SkipEmptyCells can be passed as an option to Row.ForEachCell in
// order to make it skip over empty cells in the sheet.
func SkipEmptyCells(flags *cellVisitorFlags) {
flags.skipEmptyCells = true
}

// ForEachCell will call the provided CellVisitorFunc for each
// currently defined cell in the Row.
func (r *Row) ForEachCell(cvf CellVisitorFunc) error {
fn := func(c *Cell) error {
if c != nil {
c.Row = r
return cvf(c)
// currently defined cell in the Row. Optionally you may pass one or
// more CellVisitorOption to affect how ForEachCell operates. For
// example you may wish to pass SkipEmptyCells to only visit cells
// which are populated.
func (r *Row) ForEachCell(cvf CellVisitorFunc, option ...CellVisitorOption) error {
flags := &cellVisitorFlags{}
for _, opt := range option {
opt(flags)
}
fn := func(ci int, c *Cell) error {
if c == nil {
if flags.skipEmptyCells {
return nil
}
c = r.GetCell(ci)
}
if c.Value == "" && flags.skipEmptyCells {
return nil
}
return nil
c.Row = r
return cvf(c)
}

for _, cell := range r.cells {
err := fn(cell)
for ci, cell := range r.cells {
err := fn(ci, cell)
if err != nil {
return err
}
}
cellCount := len(r.cells)
if !flags.skipEmptyCells {
for ci := cellCount; ci < r.Sheet.MaxCol; ci++ {
c := r.GetCell(ci)
err := cvf(c)
if err != nil {
return err
}

}
}

return nil
}
48 changes: 48 additions & 0 deletions row_test.go
Expand Up @@ -33,4 +33,52 @@ func TestRow(t *testing.T) {
c.Assert(cell.Value, qt.Equals, cell2.Value)
})

csRunO(c, "TestForEachCell", func(c *qt.C, option FileOption) {
var f *File
f, err := OpenFile("./testdocs/empty_cells.xlsx", option)
c.Assert(err, qt.Equals, nil)
sheet := f.Sheets[0]
c.Run("NoOptions", func(c *qt.C) {
output := [][]string{}
err := sheet.ForEachRow(func(r *Row) error {
cells := []string{}
err := r.ForEachCell(func(c *Cell) error {
cells = append(cells, c.Value)
return nil
})
if err != nil {
return err
}
c.Assert(cells, qt.HasLen, 4)
output = append(output, cells)
return nil
})
c.Assert(err, qt.Equals, nil)
})

c.Run("SkipEmptyCells", func(c *qt.C) {
output := [][]string{}
err := sheet.ForEachRow(func(r *Row) error {
cells := []string{}
err := r.ForEachCell(func(c *Cell) error {
cells = append(cells, c.Value)
return nil
}, SkipEmptyCells)
if err != nil {
return err
}
output = append(output, cells)
return nil
})
c.Assert(err, qt.Equals, nil)
c.Assert(output, qt.DeepEquals,
[][]string{
{"B1", "C1", "D1"},
{"A2", "C2", "D2"},
{"A3", "B3", "D3"},
{"A4", "B4", "C4"},
})
})

})
}

0 comments on commit f860f36

Please sign in to comment.