mirror of
https://github.com/mum4k/termdash.git
synced 2025-05-08 19:29:25 +08:00
341 lines
8.4 KiB
Go
341 lines
8.4 KiB
Go
// Copyright 2019 Google Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package table
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/kylelemons/godebug/pretty"
|
|
"github.com/mum4k/termdash/align"
|
|
"github.com/mum4k/termdash/cell"
|
|
"github.com/mum4k/termdash/internal/wrap"
|
|
)
|
|
|
|
func TestHierarchical(t *testing.T) {
|
|
tests := []struct {
|
|
desc string
|
|
columns Columns
|
|
rows []*Row
|
|
opts []ContentOption
|
|
|
|
// Got values retrieved from the first found cell.
|
|
wantHPadding int
|
|
wantVPadding int
|
|
wantAlignH align.Horizontal
|
|
wantAlignV align.Vertical
|
|
wantHeight int
|
|
wantWrapMode wrap.Mode
|
|
}{
|
|
{
|
|
desc: "defaults when not set anywhere",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCell("0"),
|
|
),
|
|
},
|
|
wantHPadding: 0,
|
|
wantVPadding: 0,
|
|
wantAlignH: align.HorizontalLeft,
|
|
wantAlignV: align.VerticalTop,
|
|
wantHeight: 0,
|
|
wantWrapMode: wrap.Never,
|
|
},
|
|
{
|
|
desc: "values set at content level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCell("0"),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
HorizontalPadding(1),
|
|
VerticalPadding(2),
|
|
AlignHorizontal(align.HorizontalCenter),
|
|
AlignVertical(align.VerticalMiddle),
|
|
ContentRowHeight(3),
|
|
WrapAtWords(),
|
|
},
|
|
wantHPadding: 1,
|
|
wantVPadding: 2,
|
|
wantAlignH: align.HorizontalCenter,
|
|
wantAlignV: align.VerticalMiddle,
|
|
wantHeight: 3,
|
|
wantWrapMode: wrap.AtWords,
|
|
},
|
|
{
|
|
desc: "values overridden at row level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRowWithOpts(
|
|
[]*Cell{
|
|
NewCell("0"),
|
|
},
|
|
RowHorizontalPadding(10),
|
|
RowVerticalPadding(20),
|
|
RowAlignHorizontal(align.HorizontalRight),
|
|
RowAlignVertical(align.VerticalBottom),
|
|
RowHeight(30),
|
|
RowWrapAtWords(),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
HorizontalPadding(1),
|
|
VerticalPadding(2),
|
|
AlignHorizontal(align.HorizontalCenter),
|
|
AlignVertical(align.VerticalMiddle),
|
|
ContentRowHeight(3),
|
|
},
|
|
wantHPadding: 10,
|
|
wantVPadding: 20,
|
|
wantAlignH: align.HorizontalRight,
|
|
wantAlignV: align.VerticalBottom,
|
|
wantHeight: 30,
|
|
wantWrapMode: wrap.AtWords,
|
|
},
|
|
{
|
|
desc: "values overridden at cell level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCellWithOpts(
|
|
[]*Data{
|
|
NewData("0"),
|
|
},
|
|
CellHorizontalPadding(10),
|
|
CellVerticalPadding(20),
|
|
CellAlignHorizontal(align.HorizontalRight),
|
|
CellAlignVertical(align.VerticalBottom),
|
|
CellHeight(30),
|
|
CellWrapAtWords(),
|
|
),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
HorizontalPadding(1),
|
|
VerticalPadding(2),
|
|
AlignHorizontal(align.HorizontalCenter),
|
|
AlignVertical(align.VerticalMiddle),
|
|
ContentRowHeight(3),
|
|
},
|
|
wantHPadding: 10,
|
|
wantVPadding: 20,
|
|
wantAlignH: align.HorizontalRight,
|
|
wantAlignV: align.VerticalBottom,
|
|
wantHeight: 30,
|
|
wantWrapMode: wrap.AtWords,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
c, err := NewContent(tc.columns, tc.rows, tc.opts...)
|
|
if err != nil {
|
|
t.Fatalf("NewContent => unexpected error: %v", err)
|
|
}
|
|
|
|
fc, err := firstCell(c)
|
|
if err != nil {
|
|
t.Fatalf("firstCell => unexpected error: %v", err)
|
|
}
|
|
|
|
ho := fc.hierarchical
|
|
if gotHPadding := ho.getHorizontalPadding(); gotHPadding != tc.wantHPadding {
|
|
t.Errorf("getHorizontalPadding => %v, want %v", gotHPadding, tc.wantHPadding)
|
|
}
|
|
if gotVPadding := ho.getVerticalPadding(); gotVPadding != tc.wantVPadding {
|
|
t.Errorf("getVerticalPadding => %v, want %v", gotVPadding, tc.wantVPadding)
|
|
}
|
|
if gotAlignH := ho.getAlignHorizontal(); gotAlignH != tc.wantAlignH {
|
|
t.Errorf("getAlignHorizontal => %v, want %v", gotAlignH, tc.wantAlignH)
|
|
}
|
|
if gotAlignV := ho.getAlignVertical(); gotAlignV != tc.wantAlignV {
|
|
t.Errorf("getAlignVertical => %v, want %v", gotAlignV, tc.wantAlignV)
|
|
}
|
|
if gotHeight := ho.getHeight(); gotHeight != tc.wantHeight {
|
|
t.Errorf("getHeight => %v, want %v", gotHeight, tc.wantHeight)
|
|
}
|
|
if gotWrapMode := ho.getWrapMode(); gotWrapMode != tc.wantWrapMode {
|
|
t.Errorf("getWrapMode => %v, want %v", gotWrapMode, tc.wantWrapMode)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// firstCell returns the first cell found in the content or an error if there
|
|
// are none.
|
|
func firstCell(c *Content) (*Cell, error) {
|
|
for _, tableRow := range c.rows {
|
|
for _, tableCell := range tableRow.cells {
|
|
return tableCell, nil
|
|
}
|
|
}
|
|
return nil, errors.New("found no table cells in the content")
|
|
}
|
|
|
|
func TestDataCellOpts(t *testing.T) {
|
|
tests := []struct {
|
|
desc string
|
|
columns Columns
|
|
rows []*Row
|
|
opts []ContentOption
|
|
// Expected options on all the data cells in order.
|
|
want []*cell.Options
|
|
}{
|
|
{
|
|
desc: "default cell options when not set anywhere",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCell("0"),
|
|
),
|
|
},
|
|
want: []*cell.Options{
|
|
cell.NewOptions(),
|
|
},
|
|
},
|
|
{
|
|
desc: "inherited from content level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCell("0"),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
ContentCellOpts(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
want: []*cell.Options{
|
|
cell.NewOptions(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
},
|
|
{
|
|
desc: "inherits only to data with default options",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCellWithOpts(
|
|
[]*Data{
|
|
NewData(
|
|
"0",
|
|
DataCellOpts(
|
|
cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack),
|
|
),
|
|
),
|
|
NewData("1"),
|
|
},
|
|
),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
ContentCellOpts(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
want: []*cell.Options{
|
|
cell.NewOptions(cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack)),
|
|
cell.NewOptions(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
},
|
|
{
|
|
desc: "overridden at row level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRowWithOpts(
|
|
[]*Cell{
|
|
NewCell("0"),
|
|
},
|
|
RowCellOpts(
|
|
cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack),
|
|
),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
ContentCellOpts(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
want: []*cell.Options{
|
|
cell.NewOptions(cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack)),
|
|
},
|
|
},
|
|
{
|
|
desc: "overridden at cell level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCellWithOpts(
|
|
[]*Data{
|
|
NewData("0"),
|
|
},
|
|
CellOpts(
|
|
cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack),
|
|
),
|
|
),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
ContentCellOpts(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
want: []*cell.Options{
|
|
cell.NewOptions(cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack)),
|
|
},
|
|
},
|
|
{
|
|
desc: "overridden at data level",
|
|
columns: Columns(1),
|
|
rows: []*Row{
|
|
NewRow(
|
|
NewCellWithOpts(
|
|
[]*Data{
|
|
NewData(
|
|
"0",
|
|
DataCellOpts(
|
|
cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack),
|
|
),
|
|
),
|
|
},
|
|
),
|
|
),
|
|
},
|
|
opts: []ContentOption{
|
|
ContentCellOpts(cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorGreen)),
|
|
},
|
|
want: []*cell.Options{
|
|
cell.NewOptions(cell.FgColor(cell.ColorBlue), cell.BgColor(cell.ColorBlack)),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
c, err := NewContent(tc.columns, tc.rows, tc.opts...)
|
|
if err != nil {
|
|
t.Fatalf("NewContent => unexpected error: %v", err)
|
|
}
|
|
|
|
var got []*cell.Options
|
|
for _, row := range c.rows {
|
|
for _, tableCell := range row.cells {
|
|
for _, dataCell := range tableCell.data.cells {
|
|
got = append(got, dataCell.Opts)
|
|
}
|
|
}
|
|
}
|
|
if diff := pretty.Compare(tc.want, got); diff != "" {
|
|
t.Errorf("NewContent => unexpected data cell options, diff (-want, +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|