mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-20 01:34:24 +08:00
add sub basic data table
This commit is contained in:
@@ -0,0 +1,87 @@
|
|||||||
|
package datatable
|
||||||
|
|
||||||
|
// SubBasicDataTable defines the structure of sub basic data table
|
||||||
|
type SubBasicDataTable struct {
|
||||||
|
baseTable BasicDataTable
|
||||||
|
fromIndex int
|
||||||
|
toIndex int
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubBasicDataTableRowIterator defines the structure of sub basic data table row iterator
|
||||||
|
type SubBasicDataTableRowIterator struct {
|
||||||
|
dataTable *SubBasicDataTable
|
||||||
|
innerIterator BasicDataTableRowIterator
|
||||||
|
currentIndex int
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataRowCount returns the total count of data row
|
||||||
|
func (t *SubBasicDataTable) DataRowCount() int {
|
||||||
|
return t.toIndex - t.fromIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderColumnNames returns the header column name list
|
||||||
|
func (t *SubBasicDataTable) HeaderColumnNames() []string {
|
||||||
|
return t.baseTable.HeaderColumnNames()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataRowIterator returns the iterator of data row
|
||||||
|
func (t *SubBasicDataTable) DataRowIterator() BasicDataTableRowIterator {
|
||||||
|
innerIterator := t.baseTable.DataRowIterator()
|
||||||
|
currentIndex := -1
|
||||||
|
|
||||||
|
// skip rows until reaching the fromIndex
|
||||||
|
for currentIndex = -1; currentIndex < t.fromIndex-1 && innerIterator.HasNext(); currentIndex++ {
|
||||||
|
innerIterator.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SubBasicDataTableRowIterator{
|
||||||
|
dataTable: t,
|
||||||
|
innerIterator: innerIterator,
|
||||||
|
currentIndex: currentIndex,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasNext returns whether the iterator does not reach the end
|
||||||
|
func (t *SubBasicDataTableRowIterator) HasNext() bool {
|
||||||
|
return t.currentIndex+1 < t.dataTable.toIndex && t.innerIterator.HasNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentRowId returns current row id
|
||||||
|
func (t *SubBasicDataTableRowIterator) CurrentRowId() string {
|
||||||
|
return t.innerIterator.CurrentRowId()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next returns the next basic data row
|
||||||
|
func (t *SubBasicDataTableRowIterator) Next() BasicDataTableRow {
|
||||||
|
if t.currentIndex+1 >= t.dataTable.toIndex {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
t.currentIndex++
|
||||||
|
return t.innerIterator.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubBasicTable returns a sub basic data table that references a portion of the original table
|
||||||
|
func CreateSubBasicTable(dataTable BasicDataTable, fromIndex, toIndex int) *SubBasicDataTable {
|
||||||
|
if fromIndex < 0 {
|
||||||
|
fromIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if fromIndex > dataTable.DataRowCount() {
|
||||||
|
fromIndex = dataTable.DataRowCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
if toIndex > dataTable.DataRowCount() {
|
||||||
|
toIndex = dataTable.DataRowCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
if toIndex < fromIndex {
|
||||||
|
toIndex = fromIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SubBasicDataTable{
|
||||||
|
baseTable: dataTable,
|
||||||
|
fromIndex: fromIndex,
|
||||||
|
toIndex: toIndex,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package datatable
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateSubBasicTable_WithValidInput(t *testing.T) {
|
||||||
|
columns := []string{"Col1", "Col2", "Col3"}
|
||||||
|
rows := []*testBasicDataTableRow{
|
||||||
|
{
|
||||||
|
rowId: "1",
|
||||||
|
rowColumns: []string{"A1", "B1", "C1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rowId: "2",
|
||||||
|
rowColumns: []string{"A2", "B2", "C2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rowId: "3",
|
||||||
|
rowColumns: []string{"A3", "B3", "C3"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
basicDataTable := &testBasicDataTable{
|
||||||
|
headerColumns: columns,
|
||||||
|
rows: rows,
|
||||||
|
}
|
||||||
|
|
||||||
|
subTable := CreateSubBasicTable(basicDataTable, 1, 2)
|
||||||
|
assert.Equal(t, 1, subTable.DataRowCount())
|
||||||
|
assert.Equal(t, columns, subTable.HeaderColumnNames())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateSubBasicTable_WithInvalidInput(t *testing.T) {
|
||||||
|
columns := []string{"Col1", "Col2", "Col3"}
|
||||||
|
rows := []*testBasicDataTableRow{
|
||||||
|
{
|
||||||
|
rowId: "1",
|
||||||
|
rowColumns: []string{"A1", "B1", "C1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rowId: "2",
|
||||||
|
rowColumns: []string{"A2", "B2", "C2"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
basicDataTable := &testBasicDataTable{
|
||||||
|
headerColumns: columns,
|
||||||
|
rows: rows,
|
||||||
|
}
|
||||||
|
|
||||||
|
subTable := CreateSubBasicTable(basicDataTable, -1, 2)
|
||||||
|
assert.Equal(t, 0, subTable.fromIndex)
|
||||||
|
assert.Equal(t, 2, subTable.toIndex)
|
||||||
|
|
||||||
|
subTable = CreateSubBasicTable(basicDataTable, 5, 2)
|
||||||
|
assert.Equal(t, 2, subTable.fromIndex)
|
||||||
|
assert.Equal(t, 2, subTable.toIndex)
|
||||||
|
|
||||||
|
subTable = CreateSubBasicTable(basicDataTable, 0, 5)
|
||||||
|
assert.Equal(t, 0, subTable.fromIndex)
|
||||||
|
assert.Equal(t, 2, subTable.toIndex)
|
||||||
|
|
||||||
|
subTable = CreateSubBasicTable(basicDataTable, 2, 1)
|
||||||
|
assert.Equal(t, 2, subTable.fromIndex)
|
||||||
|
assert.Equal(t, 2, subTable.toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSubBasicDataTable_DataRowIterator(t *testing.T) {
|
||||||
|
columns := []string{"Col1", "Col2", "Col3"}
|
||||||
|
rows := []*testBasicDataTableRow{
|
||||||
|
{
|
||||||
|
rowId: "1",
|
||||||
|
rowColumns: []string{"A1", "B1", "C1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rowId: "2",
|
||||||
|
rowColumns: []string{"A2", "B2", "C2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rowId: "3",
|
||||||
|
rowColumns: []string{"A3", "B3", "C3"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
basicDataTable := &testBasicDataTable{
|
||||||
|
headerColumns: columns,
|
||||||
|
rows: rows,
|
||||||
|
}
|
||||||
|
|
||||||
|
subTable := CreateSubBasicTable(basicDataTable, 1, 3)
|
||||||
|
iterator := subTable.DataRowIterator()
|
||||||
|
|
||||||
|
assert.True(t, iterator.HasNext())
|
||||||
|
firstRow := iterator.Next()
|
||||||
|
assert.NotNil(t, firstRow)
|
||||||
|
assert.Equal(t, "2", iterator.CurrentRowId())
|
||||||
|
assert.Equal(t, "A2", firstRow.GetData(0))
|
||||||
|
assert.Equal(t, "B2", firstRow.GetData(1))
|
||||||
|
assert.Equal(t, "C2", firstRow.GetData(2))
|
||||||
|
|
||||||
|
assert.True(t, iterator.HasNext())
|
||||||
|
secondRow := iterator.Next()
|
||||||
|
assert.NotNil(t, secondRow)
|
||||||
|
assert.Equal(t, "3", iterator.CurrentRowId())
|
||||||
|
assert.Equal(t, "A3", secondRow.GetData(0))
|
||||||
|
assert.Equal(t, "B3", secondRow.GetData(1))
|
||||||
|
assert.Equal(t, "C3", secondRow.GetData(2))
|
||||||
|
|
||||||
|
assert.False(t, iterator.HasNext())
|
||||||
|
assert.Nil(t, iterator.Next())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSubBasicDataTable_EmptyDataRange(t *testing.T) {
|
||||||
|
columns := []string{"Col1", "Col2", "Col3"}
|
||||||
|
rows := []*testBasicDataTableRow{
|
||||||
|
{
|
||||||
|
rowId: "1",
|
||||||
|
rowColumns: []string{"A1", "B1", "C1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rowId: "2",
|
||||||
|
rowColumns: []string{"A2", "B2", "C2"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
basicDataTable := &testBasicDataTable{
|
||||||
|
headerColumns: columns,
|
||||||
|
rows: rows,
|
||||||
|
}
|
||||||
|
|
||||||
|
subTable := CreateSubBasicTable(basicDataTable, 1, 1)
|
||||||
|
assert.Equal(t, 0, subTable.DataRowCount())
|
||||||
|
|
||||||
|
iterator := subTable.DataRowIterator()
|
||||||
|
assert.False(t, iterator.HasNext())
|
||||||
|
assert.Nil(t, iterator.Next())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user