Files
bubbles/table/table_test.go
T

337 lines
9.6 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package table
import (
"fmt"
"reflect"
"testing"
"github.com/charmbracelet/lipgloss/v2"
"github.com/charmbracelet/lipgloss/v2/table"
"github.com/charmbracelet/x/exp/golden"
)
// Reusable inputs
var niceMargins = lipgloss.NewStyle().Padding(0, 1)
var headers = []string{"Rank", "City", "Country", "Population"}
var rows = [][]string{
{"1", "Tokyo", "Japan", "37,274,000"},
{"2", "Delhi", "India", "32,065,760"},
{"3", "Shanghai", "China", "28,516,904"},
{"4", "Dhaka", "Bangladesh", "22,478,116"},
{"5", "São Paulo", "Brazil", "22,429,800"},
{"6", "Mexico City", "Mexico", "22,085,140"},
{"7", "Cairo", "Egypt", "21,750,020"},
{"8", "Beijing", "China", "21,333,332"},
{"9", "Mumbai", "India", "20,961,472"},
{"10", "Osaka", "Japan", "19,059,856"},
{"11", "Chongqing", "China", "16,874,740"},
{"12", "Karachi", "Pakistan", "16,839,950"},
{"13", "Istanbul", "Turkey", "15,636,243"},
{"14", "Kinshasa", "DR Congo", "15,628,085"},
{"15", "Lagos", "Nigeria", "15,387,639"},
{"16", "Buenos Aires", "Argentina", "15,369,919"},
}
// Tests
func TestNew(t *testing.T) {
headers := []string{"Rank", "City", "Country", "Population"}
rows := [][]string{
{"1", "Tokyo", "Japan", "37,274,000"},
{"2", "Delhi", "India", "32,065,760"},
{"3", "Shanghai", "China", "28,516,904"},
{"4", "Dhaka", "Bangladesh", "22,478,116"},
{"5", "São Paulo", "Brazil", "22,429,800"},
{"6", "Mexico City", "Mexico", "22,085,140"},
{"7", "Cairo", "Egypt", "21,750,020"},
{"8", "Beijing", "China", "21,333,332"},
{"9", "Mumbai", "India", "20,961,472"},
{"10", "Osaka", "Japan", "19,059,856"},
}
t.Run("new with options", func(t *testing.T) {
tb := New(
WithHeaders(headers...),
WithRows(rows...),
WithHeight(10),
)
tb.View()
})
t.Run("new, no options", func(t *testing.T) {
tb := New().SetHeaders(headers...).SetRows(rows...)
tb.View()
})
}
func TestFromValues(t *testing.T) {
input := "foo1,bar1\nfoo2,bar2\nfoo3,bar3"
table := New(WithHeaders("Foo", "Bar"))
table.FromValues(input, ",")
if len(table.rows) != 3 {
t.Fatalf("expect table to have 3 rows but it has %d", len(table.rows))
}
expect := [][]string{
{"foo1", "bar1"},
{"foo2", "bar2"},
{"foo3", "bar3"},
}
if !reflect.DeepEqual(table.rows, expect) {
t.Fatal("table rows is not equals to the input")
}
}
func TestFromValuesWithTabSeparator(t *testing.T) {
input := "foo1.\tbar1\nfoo,bar,baz\tbar,2"
table := New(WithHeaders("Foo", "Bar"))
table.FromValues(input, "\t")
if len(table.rows) != 2 {
t.Fatalf("expect table to have 2 rows but it has %d", len(table.rows))
}
expect := [][]string{
{"foo1.", "bar1"},
{"foo,bar,baz", "bar,2"},
}
if !reflect.DeepEqual(table.rows, expect) {
t.Fatal("table rows is not equals to the input")
}
}
func TestTableAlignment(t *testing.T) {
headers := []string{
"Name",
"Country of Origin",
"Dunk-able",
}
rows := [][]string{
{"Chocolate Digestives", "UK", "Yes"},
{"Tim Tams", "Australia", "No"},
{"Hobnobs", "UK", "Yes"},
}
t.Run("No border", func(t *testing.T) {
biscuits := New(
WithHeaders(headers...),
WithRows(rows...),
).
// Remove default border.
SetBorder(false).
// Remove default border under header.
BorderHeader(false).
// Strip styles.
SetStyleFunc(func(_, _ int) lipgloss.Style {
return niceMargins
})
golden.RequireEqual(t, []byte(biscuits.View()))
})
t.Run("With border", func(t *testing.T) {
// TODO how do we style header border?
// s.Header = s.Header.
// BorderStyle(lipgloss.NormalBorder()).
// BorderForeground(lipgloss.Color("240")).
// Bold(false)
biscuits := New(
WithHeaders(headers...),
WithRows(rows...),
).
// Strip styles
SetStyleFunc(func(_, _ int) lipgloss.Style {
return niceMargins
})
golden.RequireEqual(t, []byte(biscuits.View()))
})
}
// Test Styles
func TestOverwriteStyles(t *testing.T) {
tests := []struct {
name string
styles Styles
}{
{"clear styles", Styles{
Selected: lipgloss.NewStyle(),
Header: lipgloss.NewStyle(),
Cell: lipgloss.NewStyle(),
}},
{"new styles", Styles{
Selected: niceMargins.Foreground(lipgloss.Color("68")),
Header: niceMargins,
Cell: niceMargins,
}},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
tb := New(
WithHeaders(headers...),
WithRows(rows...),
WithFocused(true),
WithHeight(10),
)
tb.OverwriteStyles(tc.styles)
golden.RequireEqual(t, []byte(tb.View()))
})
}
}
func TestSetStyles(t *testing.T) {
tests := []struct {
name string
styles Styles
}{
{"empty styles; do nothing", Styles{
Selected: lipgloss.NewStyle(),
Header: lipgloss.NewStyle(),
Cell: lipgloss.NewStyle(),
}},
{"new styles", Styles{
Selected: niceMargins.Background(lipgloss.Color("68")),
Header: niceMargins,
Cell: niceMargins,
}},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
table := New(
WithHeaders(headers...),
WithRows(rows...),
WithFocused(true),
WithHeight(10),
)
table.SetStyles(tc.styles)
golden.RequireEqual(t, []byte(table.View()))
})
}
}
func TestSetStyleFunc(t *testing.T) {
t.Run("Clear styles with StyleFunc", func(t *testing.T) {
tb := New(
WithHeaders(headers...),
WithRows(rows...),
WithFocused(true),
WithHeight(10),
)
tb.SetStyleFunc(table.StyleFunc(func(row, col int) lipgloss.Style {
if row == tb.Cursor() {
return niceMargins.Background(lipgloss.Color("68"))
}
return niceMargins
}))
golden.RequireEqual(t, []byte(tb.View()))
})
}
func TestSetBorder(t *testing.T) {
tests := []struct {
name string
borders []bool
}{
{"unset all borders", []bool{false}},
{"set all borders", []bool{true}},
{"vertical borders only", []bool{true, false}},
{"no top border", []bool{false, true, true}},
{"no left border", []bool{true, true, true, false}},
{"row separator and no right border", []bool{true, false, true, true, true}},
{"set row and column separators", []bool{false, false, false, false, true, true}},
{"invalid number of arguments", []bool{true, false, false, false, false, true, true}},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
tb := New(
WithHeaders(headers...),
WithRows(rows...),
WithFocused(true),
WithHeight(10),
).SetBorder(tc.borders...)
golden.RequireEqual(t, []byte(tb.View()))
})
}
}
// Examples
func ExampleOption() {
var niceMargins = lipgloss.NewStyle().Padding(0, 1)
var headers = []string{"Rank", "City", "Country", "Population"}
var rows = [][]string{
{"1", "Tokyo", "Japan", "37,274,000"},
{"2", "Delhi", "India", "32,065,760"},
{"3", "Shanghai", "China", "28,516,904"},
{"4", "Dhaka", "Bangladesh", "22,478,116"},
{"5", "São Paulo", "Brazil", "22,429,800"},
{"6", "Mexico City", "Mexico", "22,085,140"},
{"7", "Cairo", "Egypt", "21,750,020"},
{"8", "Beijing", "China", "21,333,332"},
{"9", "Mumbai", "India", "20,961,472"},
{"10", "Osaka", "Japan", "19,059,856"},
}
t := New(
WithHeaders(headers...),
WithRows(rows...),
WithFocused(true),
WithHeight(10),
).OverwriteStyles(Styles{
Selected: niceMargins,
Header: niceMargins,
Cell: niceMargins,
})
fmt.Println(t.View())
// Output:
//┌───────────────────────────────────────────┐
//│ Rank  City   Country   Population │
//├───────────────────────────────────────────┤
//│ 1   Tokyo   Japan   37,274,000 │
//│ 2   Delhi   India   32,065,760 │
//│ 3   Shanghai   China   28,516,904 │
//│ 4   Dhaka   Bangladesh  22,478,116 │
//│ 5   São Paulo   Brazil   22,429,800 │
//│ …   …   …   …  │
//└───────────────────────────────────────────┘
}
func ExampleModel_SetRows() {
var niceMargins = lipgloss.NewStyle().Padding(0, 1)
var headers = []string{"Rank", "City", "Country", "Population"}
var rows = [][]string{
{"1", "Tokyo", "Japan", "37,274,000"},
{"2", "Delhi", "India", "32,065,760"},
{"3", "Shanghai", "China", "28,516,904"},
{"4", "Dhaka", "Bangladesh", "22,478,116"},
{"5", "São Paulo", "Brazil", "22,429,800"},
{"6", "Mexico City", "Mexico", "22,085,140"},
{"7", "Cairo", "Egypt", "21,750,020"},
{"8", "Beijing", "China", "21,333,332"},
{"9", "Mumbai", "India", "20,961,472"},
{"10", "Osaka", "Japan", "19,059,856"},
}
tb := New().
SetHeaders(headers...).
SetRows(rows...).
SetHeight(10).
OverwriteStyles(Styles{
Selected: niceMargins,
Header: niceMargins,
Cell: niceMargins,
})
fmt.Println(tb.View())
// Output:
//┌───────────────────────────────────────────┐
//│ Rank  City   Country   Population │
//├───────────────────────────────────────────┤
//│ 1   Tokyo   Japan   37,274,000 │
//│ 2   Delhi   India   32,065,760 │
//│ 3   Shanghai   China   28,516,904 │
//│ 4   Dhaka   Bangladesh  22,478,116 │
//│ 5   São Paulo   Brazil   22,429,800 │
//│ …   …   …   …  │
//└───────────────────────────────────────────┘
}