From 3819df4fec01e7da0c2545aa1c5fac02af7ff4b5 Mon Sep 17 00:00:00 2001 From: Naveen Mahalingam Date: Fri, 5 Apr 2024 09:04:46 -0700 Subject: [PATCH] table: fix paging with separators; fixes #312 --- go.mod | 4 +- go.sum | 8 +- table/render.go | 52 +++++++++++-- table/render_test.go | 180 +++++++++++++++++++++++++++++++------------ table/table_test.go | 10 +++ 5 files changed, 193 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index bc0a3d2..d9dc0f0 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( github.com/mattn/go-runewidth v0.0.15 github.com/pkg/profile v1.7.0 github.com/stretchr/testify v1.8.4 - golang.org/x/sys v0.16.0 - golang.org/x/term v0.16.0 + golang.org/x/sys v0.17.0 + golang.org/x/term v0.17.0 ) require ( diff --git a/go.sum b/go.sum index 2b8531e..50378e4 100644 --- a/go.sum +++ b/go.sum @@ -25,10 +25,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/table/render.go b/table/render.go index 2e93da5..7aacd00 100644 --- a/table/render.go +++ b/table/render.go @@ -211,7 +211,7 @@ func (t *Table) renderLine(out *strings.Builder, row rowStr, hint renderHint) { // if a page size has been set, and said number of lines has already // been rendered, and the header is not being rendered right now, render // the header all over again with a spacing line - if hint.isRegularRow() { + if hint.isRegularNonSeparatorRow() { t.numLinesRendered++ if t.pageSize > 0 && t.numLinesRendered%t.pageSize == 0 && !hint.isLastLineOfLastRow() { t.renderRowsFooter(out) @@ -313,27 +313,65 @@ func (t *Table) renderRows(out *strings.Builder, rows []rowStr, hint renderHint) hint.rowNumber = rowIdx + 1 t.renderRow(out, row, hint) - if (t.style.Options.SeparateRows && rowIdx < len(rows)-1) || // last row before footer - (t.separators[rowIdx] && rowIdx != len(rows)-1) { // manually added separator not after last row + if t.shouldSeparate(rowIdx, len(rows)) { hint.isFirstRow = false t.renderRowSeparator(out, hint) } } } +func (t *Table) shouldSeparate(rowIdx int, numRows int) bool { + // last row before footer + if t.style.Options.SeparateRows && rowIdx < numRows-1 { + return true + } + // no manually added separator + if !t.separators[rowIdx] { + return false + } + + pageSize := numRows + if t.pageSize > 0 { + pageSize = t.pageSize + } + if rowIdx%pageSize == pageSize-1 { // last row of page + return false + } + if rowIdx == numRows-1 { // last row of table + return false + } + return true +} + func (t *Table) renderRowsBorderBottom(out *strings.Builder) { if len(t.rowsFooter) > 0 { - t.renderRowSeparator(out, renderHint{isBorderBottom: true, isFooterRow: true, rowNumber: len(t.rowsFooter)}) + t.renderRowSeparator(out, renderHint{ + isBorderBottom: true, + isFooterRow: true, + rowNumber: len(t.rowsFooter), + }) } else { - t.renderRowSeparator(out, renderHint{isBorderBottom: true, isFooterRow: false, rowNumber: len(t.rows)}) + t.renderRowSeparator(out, renderHint{ + isBorderBottom: true, + isFooterRow: false, + rowNumber: len(t.rows), + }) } } func (t *Table) renderRowsBorderTop(out *strings.Builder) { if len(t.rowsHeader) > 0 || t.autoIndex { - t.renderRowSeparator(out, renderHint{isBorderTop: true, isHeaderRow: true, rowNumber: 0}) + t.renderRowSeparator(out, renderHint{ + isBorderTop: true, + isHeaderRow: true, + rowNumber: 0, + }) } else { - t.renderRowSeparator(out, renderHint{isBorderTop: true, isHeaderRow: false, rowNumber: 0}) + t.renderRowSeparator(out, renderHint{ + isBorderTop: true, + isHeaderRow: false, + rowNumber: 0, + }) } } diff --git a/table/render_test.go b/table/render_test.go index 7018bc0..55db354 100644 --- a/table/render_test.go +++ b/table/render_test.go @@ -794,60 +794,144 @@ func TestTable_Render_HiddenColumns(t *testing.T) { func TestTable_Render_Paged(t *testing.T) { tw := NewWriter() - tw.AppendHeader(testHeader) - tw.AppendRows(testRows) - tw.AppendRow(testRowMultiLine) - tw.AppendFooter(Row{"", "", "Total", 10000}) - tw.SetPageSize(1) + tw.AppendHeader(testTitanicHeader) + tw.AppendRows(testTitanicRows) compareOutput(t, tw.Render(), ` -+-----+------------+-----------+--------+-----------------------------+ -| # | FIRST NAME | LAST NAME | SALARY | | -+-----+------------+-----------+--------+-----------------------------+ -| 1 | Arya | Stark | 3000 | | -+-----+------------+-----------+--------+-----------------------------+ -| | | TOTAL | 10000 | | -+-----+------------+-----------+--------+-----------------------------+ - -+-----+------------+-----------+--------+-----------------------------+ -| # | FIRST NAME | LAST NAME | SALARY | | -+-----+------------+-----------+--------+-----------------------------+ -| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | -+-----+------------+-----------+--------+-----------------------------+ -| | | TOTAL | 10000 | | -+-----+------------+-----------+--------+-----------------------------+ ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | | S | +| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | +| 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | | S | +| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | +| 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+`) + + tw.SetPageSize(3) + compareOutput(t, tw.Render(), ` ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | | S | +| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | +| 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | +| 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+`) -+-----+------------+-----------+--------+-----------------------------+ -| # | FIRST NAME | LAST NAME | SALARY | | -+-----+------------+-----------+--------+-----------------------------+ -| 300 | Tyrion | Lannister | 5000 | | -+-----+------------+-----------+--------+-----------------------------+ -| | | TOTAL | 10000 | | -+-----+------------+-----------+--------+-----------------------------+ + tw.SetPageSize(1) + compareOutput(t, tw.Render(), ` ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+`) +} -+-----+------------+-----------+--------+-----------------------------+ -| # | FIRST NAME | LAST NAME | SALARY | | -+-----+------------+-----------+--------+-----------------------------+ -| 0 | Winter | Is | 0 | Coming. | -+-----+------------+-----------+--------+-----------------------------+ -| | | TOTAL | 10000 | | -+-----+------------+-----------+--------+-----------------------------+ +func TestTable_Render_PagedAndSeparated(t *testing.T) { + tw := NewWriter() + tw.AppendHeader(testTitanicHeader) + for _, row := range testTitanicRows { + tw.AppendRow(row) + tw.AppendSeparator() + } -+-----+------------+-----------+--------+-----------------------------+ -| # | FIRST NAME | LAST NAME | SALARY | | -+-----+------------+-----------+--------+-----------------------------+ -| | | | | The North Remembers! | -+-----+------------+-----------+--------+-----------------------------+ -| | | TOTAL | 10000 | | -+-----+------------+-----------+--------+-----------------------------+ + compareOutput(t, tw.Render(), ` ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+`) + + tw.SetPageSize(3) + compareOutput(t, tw.Render(), ` ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+`) -+-----+------------+-----------+--------+-----------------------------+ -| # | FIRST NAME | LAST NAME | SALARY | | -+-----+------------+-----------+--------+-----------------------------+ -| | | | | This is known. | -+-----+------------+-----------+--------+-----------------------------+ -| | | TOTAL | 10000 | | -+-----+------------+-----------+--------+-----------------------------+`) + tw.SetPageSize(1) + compareOutput(t, tw.Render(), ` ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ + ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+ +| 5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | | S | ++-------------+----------+--------+-----------------------------------------------------+--------+-----+-------+-------+------------------+---------+-------+----------+`) } func TestTable_Render_Reset(t *testing.T) { diff --git a/table/table_test.go b/table/table_test.go index 9addf88..8c52bb6 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -25,6 +25,16 @@ var ( {20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"}, {300, "Tyrion", "Lannister", 5000}, } + testTitanicHeader = Row{ + "PassengerId", "Survived", "Pclass", "Name", "Sex", "Age", "SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked", + } + testTitanicRows = []Row{ + {"1", "0", "3", "Braund, Mr. Owen Harris", "male", "22", "1", "0", "A/5 21171", "7.25", "", "S"}, + {"2", "1", "1", "Cumings, Mrs. John Bradley (Florence Briggs Thayer)", "female", "38", "1", "0", "PC 17599", "71.2833", "C85", "C"}, + {"3", "1", "3", "Heikkinen, Miss. Laina", "female", "26", "0", "0", "STON/O2. 3101282", "7.925", "", "S"}, + {"4", "1", "1", "Futrelle, Mrs. Jacques Heath (Lily May Peel)", "female", "35", "1", "0", "113803", "53.1", "C123", "S"}, + {"5", "0", "3", "Allen, Mr. William Henry", "male", "35", "0", "0", "373450", "8.05", "", "S"}, + } testRowMultiLine = Row{0, "Winter", "Is", 0, "Coming.\r\nThe North Remembers!\nThis is known."} testRowNewLines = Row{0, "Valar", "Morghulis", 0, "Faceless\nMen"} testRowPipes = Row{0, "Valar", "Morghulis", 0, "Faceless|Men"}