mirror of
https://github.com/charmbracelet/lipgloss.git
synced 2024-09-11 14:07:21 +03:00
* feat: implement list renderer * feat: data model for list * feat: add Offset, Height, Indent * feat: tree renderer * fix: list example * test: last tree node is a subtree Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: tree Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: lint Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * docs: example Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * test: inc cov Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: multiline items Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * feat: one approach to sublists Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: tree improvements * wip Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * wip Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * wip Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * wip Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: prevent having to pass renderer to all trees * test: force linux line endings * fix: windows * fix: lint issues * fix: ignore lint issue failing forever * fix: renames * fix: renderer * ci: fix coveralls hopefully * wip Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: style * docs: update Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: renderer Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * test: cover with tests Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * feat: more list enumerators * fix: drop renderer api Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * feat: improve api Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: prealloc * fix: clean up * fix: list setup * fix: improve sublist tests * fix: improve sublists * refactor: simplify * docs: more examples, readme updates Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * docs: readme * fix: set item style * fix(tree): do not use golden files * test: do not use golden files * refactor: remove unused code * feat: hide nodes * feat: filter * fix: allow fmt.Stringer * test: table within a tree * docs: update * fix: rename atter to data * test: test public api only * docs: sublist with table example * docs: update example * fix: lint issues Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * docs: update examples * docs: update * feat: offset * feat: offsetstart && offsetend * fix: remove last from enumerator * refactor: make tree more explicit * `New()` now take no args * added a new `Root(string)` method * added a new `Items(...any)` method * refactor: improve list * docs: fix examples * test: ensure embed lists in trees * docs: sublist example with list as tree node Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * refactor: first pass at examples cleanup * refactor: first pass at examples cleanup * fix: support multi-line prefixes * test: more glow-style lists within trees * docs: simplify examples * fix: improve handling of different types * chore: go mod tidy Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: code review suggestions Co-authored-by: Ayman Bagabas <ayman.bagabas@gmail.com> Co-authored-by: bashbunni <15822994+bashbunni@users.noreply.github.com> * fix: apply code review suggestion * feat(tree): rounded enumerator (#280) * chore(examples): go mod tidy * feat(tree): add rounded corner enumerator * test: rounded enumerator test * docs: readme updates Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * docs: readme updates Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * chore: fmt Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * docs: godoc * docs: godoc * fix: bash's issue * fix: bad example Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * docs: improve godoc for trees and lists (#296) * docs(godoc): add overview * docs(godoc): include examples in godoc * docs(godoc): fix roman numerals example * docs(godoc): fix tree examples * docs(godoc): attempt to fix list Enumerator examples * docs: added some examples to godoc * fix(list): New(items...) with sublist * docs: update examples * chore(tree): improve var names in rounded example * fix: use padding instead of margin to better styles * fix: lint --------- Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> Co-authored-by: Maas Lalani <maas@lalani.dev> Co-authored-by: Ayman Bagabas <ayman.bagabas@gmail.com> Co-authored-by: bashbunni <15822994+bashbunni@users.noreply.github.com> Co-authored-by: Christian Rocha <christian@rocha.is>
877 lines
16 KiB
Go
877 lines
16 KiB
Go
package tree_test
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
"github.com/charmbracelet/lipgloss/internal/require"
|
|
"github.com/charmbracelet/lipgloss/list"
|
|
"github.com/charmbracelet/lipgloss/table"
|
|
"github.com/charmbracelet/lipgloss/tree"
|
|
)
|
|
|
|
func ExampleNew() {
|
|
tree := tree.New().
|
|
Item("First")
|
|
fmt.Print(tree)
|
|
// Output: └── First
|
|
}
|
|
|
|
func ExampleNew_root() {
|
|
tree := tree.New().
|
|
Root("Root")
|
|
fmt.Print(tree)
|
|
// Output: Root
|
|
}
|
|
|
|
func ExampleNew_round() {
|
|
tree := tree.New().
|
|
Enumerator(tree.RoundedEnumerator).
|
|
Item("First")
|
|
fmt.Print(tree)
|
|
// Output: ╰── First
|
|
}
|
|
|
|
func TestTree(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux",
|
|
tree.New().
|
|
Root("Quux").
|
|
Items(
|
|
"Foo",
|
|
"Bar",
|
|
),
|
|
"Quuux",
|
|
),
|
|
"Baz",
|
|
)
|
|
|
|
expected := `
|
|
├── Foo
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ ├── Quux
|
|
│ │ ├── Foo
|
|
│ │ └── Bar
|
|
│ └── Quuux
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeRounded(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux",
|
|
tree.New().
|
|
Root("Quux").
|
|
Items(
|
|
"Foo",
|
|
"Bar",
|
|
),
|
|
"Quuux",
|
|
),
|
|
"Baz",
|
|
).
|
|
Enumerator(tree.RoundedEnumerator)
|
|
|
|
expected := `
|
|
├── Foo
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ ├── Quux
|
|
│ │ ├── Foo
|
|
│ │ ╰── Bar
|
|
│ ╰── Quuux
|
|
╰── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeHidden(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux",
|
|
tree.New().
|
|
Root("Quux").
|
|
Items("Foo", "Bar").
|
|
Hide(true),
|
|
"Quuux",
|
|
),
|
|
"Baz",
|
|
)
|
|
|
|
expected := `
|
|
├── Foo
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ └── Quuux
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeAllHidden(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux",
|
|
tree.New().
|
|
Root("Quux").
|
|
Items(
|
|
"Foo",
|
|
"Bar",
|
|
),
|
|
"Quuux",
|
|
),
|
|
"Baz",
|
|
).Hide(true)
|
|
|
|
expected := ``
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeRoot(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("The Root").
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items("Qux", "Quuux"),
|
|
"Baz",
|
|
)
|
|
expected := `
|
|
The Root
|
|
├── Foo
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ └── Quuux
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeStartsWithSubtree(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
tree.New().
|
|
Root("Bar").
|
|
Items("Qux", "Quuux"),
|
|
"Baz",
|
|
)
|
|
|
|
expected := `
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ └── Quuux
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeAddTwoSubTreesWithoutName(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"bar",
|
|
"foo",
|
|
tree.New().
|
|
Items(
|
|
"Bar 11",
|
|
"Bar 12",
|
|
"Bar 13",
|
|
"Bar 14",
|
|
"Bar 15",
|
|
),
|
|
tree.New().
|
|
Items(
|
|
"Bar 21",
|
|
"Bar 22",
|
|
"Bar 23",
|
|
"Bar 24",
|
|
"Bar 25",
|
|
),
|
|
"Baz",
|
|
)
|
|
|
|
expected := `
|
|
├── bar
|
|
├── foo
|
|
│ ├── Bar 11
|
|
│ ├── Bar 12
|
|
│ ├── Bar 13
|
|
│ ├── Bar 14
|
|
│ ├── Bar 15
|
|
│ ├── Bar 21
|
|
│ ├── Bar 22
|
|
│ ├── Bar 23
|
|
│ ├── Bar 24
|
|
│ └── Bar 25
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeLastNodeIsSubTree(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux",
|
|
tree.New().
|
|
Root("Quux").
|
|
Items("Foo", "Bar"),
|
|
"Quuux",
|
|
),
|
|
)
|
|
|
|
expected := `
|
|
├── Foo
|
|
└── Bar
|
|
├── Qux
|
|
├── Quux
|
|
│ ├── Foo
|
|
│ └── Bar
|
|
└── Quuux
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeNil(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
nil,
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux",
|
|
tree.New().
|
|
Root("Quux").
|
|
Item("Bar"),
|
|
"Quuux",
|
|
),
|
|
"Baz",
|
|
)
|
|
|
|
expected := `
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ ├── Quux
|
|
│ │ └── Bar
|
|
│ └── Quuux
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeCustom(t *testing.T) {
|
|
quuux := tree.StringNode("Quuux")
|
|
tree := tree.New().
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
tree.StringNode("Qux"),
|
|
tree.New().
|
|
Root("Quux").
|
|
Items("Foo",
|
|
"Bar",
|
|
),
|
|
&quuux,
|
|
),
|
|
"Baz",
|
|
).
|
|
ItemStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("9"))).
|
|
EnumeratorStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("12")).PaddingRight(1)).
|
|
Enumerator(func(tree.Data, int) (indent string, prefix string) {
|
|
return "->", "->"
|
|
})
|
|
|
|
expected := `
|
|
-> Foo
|
|
-> Bar
|
|
-> -> Qux
|
|
-> -> Quux
|
|
-> -> -> Foo
|
|
-> -> -> Bar
|
|
-> -> Quuux
|
|
-> Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeMultilineNode(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("Multiline\nRoot\nNode").
|
|
Items(
|
|
"Foo",
|
|
tree.New().
|
|
Root("Bar").
|
|
Items(
|
|
"Qux\nLine 2\nLine 3\nLine 4",
|
|
tree.New().
|
|
Root("Quux").
|
|
Items(
|
|
"Foo",
|
|
"Bar",
|
|
),
|
|
"Quuux",
|
|
),
|
|
"Baz\nLine 2",
|
|
)
|
|
|
|
expected := `
|
|
Multiline
|
|
Root
|
|
Node
|
|
├── Foo
|
|
├── Bar
|
|
│ ├── Qux
|
|
│ │ Line 2
|
|
│ │ Line 3
|
|
│ │ Line 4
|
|
│ ├── Quux
|
|
│ │ ├── Foo
|
|
│ │ └── Bar
|
|
│ └── Quuux
|
|
└── Baz
|
|
Line 2
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeSubTreeWithCustomRenderer(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("The Root Node(tm)").
|
|
Items(
|
|
tree.New().
|
|
Root("Parent").
|
|
Items("child 1", "child 2").
|
|
ItemStyleFunc(func(tree.Data, int) lipgloss.Style {
|
|
return lipgloss.NewStyle().
|
|
SetString("*")
|
|
}).
|
|
EnumeratorStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
|
|
return lipgloss.NewStyle().
|
|
SetString("+").
|
|
PaddingRight(1)
|
|
}),
|
|
"Baz",
|
|
)
|
|
|
|
expected := `
|
|
The Root Node(tm)
|
|
├── Parent
|
|
│ + ├── * child 1
|
|
│ + └── * child 2
|
|
└── Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeMixedEnumeratorSize(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("The Root Node(tm)").
|
|
Items(
|
|
"child 1",
|
|
"child 2",
|
|
"child 3",
|
|
"child 4",
|
|
"child 5",
|
|
).Enumerator(func(_ tree.Data, i int) (indent string, prefix string) {
|
|
romans := map[int]string{
|
|
1: "I",
|
|
2: "II",
|
|
3: "III",
|
|
4: "IV",
|
|
5: "V",
|
|
6: "VI",
|
|
}
|
|
return "", romans[i+1]
|
|
})
|
|
|
|
expected := `
|
|
The Root Node(tm)
|
|
I child 1
|
|
II child 2
|
|
III child 3
|
|
IV child 4
|
|
V child 5
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeStyleNilFuncs(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("Multiline").
|
|
Items("Foo", "Baz").
|
|
ItemStyleFunc(nil).
|
|
EnumeratorStyleFunc(nil)
|
|
|
|
expected := `
|
|
Multiline
|
|
├──Foo
|
|
└──Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeStyleAt(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("Multiline").
|
|
Items(
|
|
"Foo",
|
|
"Baz",
|
|
).Enumerator(func(data tree.Data, i int) (indent string, prefix string) {
|
|
if data.At(i).Name() == "Foo" {
|
|
return "", ">"
|
|
}
|
|
return "", "-"
|
|
})
|
|
|
|
expected := `
|
|
Multiline
|
|
> Foo
|
|
- Baz
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestAt(t *testing.T) {
|
|
nodes := tree.NewStringData("foo", "bar")
|
|
t.Run("0", func(t *testing.T) {
|
|
if s := nodes.At(0).String(); s != "foo" {
|
|
t.Errorf("expected 'foo', got '%s'", s)
|
|
}
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
if n := nodes.At(10); n != nil {
|
|
t.Errorf("expected nil, got '%s'", n)
|
|
}
|
|
})
|
|
t.Run("-1", func(t *testing.T) {
|
|
if n := nodes.At(10); n != nil {
|
|
t.Errorf("expected nil, got '%s'", n)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestFilter(t *testing.T) {
|
|
data := tree.NewFilter(tree.NewStringData("Foo", "Bar", "Baz", "Nope")).
|
|
Filter(func(index int) bool {
|
|
return index != 1
|
|
}).
|
|
Append(tree.StringNode("Qux")).
|
|
Remove(3)
|
|
tree := tree.New().Root("Root").Item(data)
|
|
|
|
expected := `
|
|
Root
|
|
├── Foo
|
|
├── Baz
|
|
└── Qux
|
|
`
|
|
|
|
require.Equal(t, expected, tree.String())
|
|
if got := data.At(1); got.Name() != "Baz" {
|
|
t.Errorf("expected to get Baz, got %v", got)
|
|
}
|
|
if got := data.At(10); got != nil {
|
|
t.Errorf("expected to get nil, got %v", got)
|
|
}
|
|
}
|
|
|
|
func TestNodeDataRemoveOutOfBounds(t *testing.T) {
|
|
data := tree.NewStringData("a").Remove(-1).Remove(1)
|
|
if l := data.Length(); l != 1 {
|
|
t.Errorf("expected data to contain 1 items, has %d", l)
|
|
}
|
|
}
|
|
|
|
func TestTreeTable(t *testing.T) {
|
|
tree := tree.New().
|
|
Items(
|
|
"a",
|
|
tree.New().
|
|
Root("b").
|
|
Items(
|
|
"c",
|
|
"d",
|
|
table.New().
|
|
Width(40).
|
|
Headers("a", "b").
|
|
Row("1", "2").
|
|
Row("3", "4"),
|
|
"e",
|
|
),
|
|
"c",
|
|
)
|
|
expected := `
|
|
├── a
|
|
├── b
|
|
│ ├── c
|
|
│ ├── d
|
|
│ ├── ╭───────────────────┬──────────────────╮
|
|
│ │ │a │b │
|
|
│ │ ├───────────────────┼──────────────────┤
|
|
│ │ │1 │2 │
|
|
│ │ │3 │4 │
|
|
│ │ ╰───────────────────┴──────────────────╯
|
|
│ └── e
|
|
└── c
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTreeOffset(t *testing.T) {
|
|
enum := func(tree.Data, int) (string, string) {
|
|
return "", "*"
|
|
}
|
|
|
|
t.Run("start", func(t *testing.T) {
|
|
t.Run("min", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetStart(0).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
* a
|
|
* b
|
|
* c
|
|
* d
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
|
|
t.Run("in bounds", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetStart(2).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
* c
|
|
* d
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
|
|
t.Run("max", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetStart(4).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
t.Run("out bounds", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetStart(6).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
})
|
|
t.Run("end", func(t *testing.T) {
|
|
t.Run("min", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetEnd(0).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
* a
|
|
* b
|
|
* c
|
|
* d
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
|
|
t.Run("in bounds", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetEnd(2).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
* a
|
|
* b
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
|
|
t.Run("max", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetEnd(4).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
t.Run("out bounds", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetEnd(6).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
})
|
|
|
|
t.Run("start and end", func(t *testing.T) {
|
|
tree := tree.New().
|
|
Root("root").
|
|
Items("a", "b", "c", "d").
|
|
OffsetStart(1).
|
|
OffsetEnd(2).
|
|
Enumerator(enum)
|
|
|
|
expected := `
|
|
root
|
|
* b
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
})
|
|
}
|
|
|
|
func TestAddItemWithoutRootAndWithRoot(t *testing.T) {
|
|
t1 := tree.New().
|
|
Items(
|
|
"foo",
|
|
"bar",
|
|
tree.New().
|
|
Item("zaz"),
|
|
"qux",
|
|
)
|
|
t2 := tree.New().
|
|
Items(
|
|
"foo",
|
|
tree.New().
|
|
Root("bar").
|
|
Item("zaz"),
|
|
"qux",
|
|
)
|
|
expected := `
|
|
├── foo
|
|
├── bar
|
|
│ └── zaz
|
|
└── qux
|
|
`
|
|
require.Equal(t, expected, t1.String())
|
|
require.Equal(t, expected, t2.String())
|
|
}
|
|
|
|
func TestEmbedListWithinTree(t *testing.T) {
|
|
t1 := tree.New().
|
|
Item(list.New("A", "B", "C").Enumerator(list.Arabic)).
|
|
Item(list.New("1", "2", "3").Enumerator(list.Alphabet))
|
|
expected := `
|
|
├── 1. A
|
|
│ 2. B
|
|
│ 3. C
|
|
└── A. 1
|
|
B. 2
|
|
C. 3
|
|
`
|
|
require.Equal(t, expected, t1.String())
|
|
}
|
|
|
|
func TestMultilinePrefix(t *testing.T) {
|
|
paddingsStyle := lipgloss.NewStyle().PaddingLeft(1).PaddingBottom(1)
|
|
tree := tree.New().
|
|
Enumerator(func(_ tree.Data, i int) (string, string) {
|
|
if i == 1 {
|
|
return "", "│\n│"
|
|
}
|
|
return "", " "
|
|
}).
|
|
ItemStyle(paddingsStyle).
|
|
Item("Document 0\nSome tagline").
|
|
Item("Document 1\nHello world").
|
|
Item("Document 2\nSome other tagline")
|
|
expected := `
|
|
Document 0
|
|
Some tagline
|
|
|
|
│ Document 1
|
|
│ Hello world
|
|
|
|
Document 2
|
|
Some other tagline
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestMultilinePrefixSingleLineItem(t *testing.T) {
|
|
paddingsStyle := lipgloss.NewStyle().PaddingLeft(1).PaddingBottom(1)
|
|
tree := tree.New().
|
|
Enumerator(func(_ tree.Data, i int) (string, string) {
|
|
if i == 1 {
|
|
return "", "│\n│"
|
|
}
|
|
return "", " "
|
|
}).
|
|
ItemStyle(paddingsStyle).
|
|
Item("Document 0\nhello").
|
|
Item("Document 1\n").
|
|
Item("Document 2\nhello again")
|
|
expected := `
|
|
Document 0
|
|
hello
|
|
|
|
│ Document 1
|
|
│
|
|
|
|
Document 2
|
|
hello again
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestMultilinePrefixSubtree(t *testing.T) {
|
|
paddingsStyle := lipgloss.NewStyle().PaddingLeft(1).PaddingBottom(1)
|
|
tree := tree.New().
|
|
Item("Hello").
|
|
Item("Foo").
|
|
Item(
|
|
tree.New().
|
|
Root("Bar").
|
|
Enumerator(func(_ tree.Data, i int) (string, string) {
|
|
if i == 1 {
|
|
return "", "│\n│"
|
|
}
|
|
return "", " "
|
|
}).
|
|
ItemStyle(paddingsStyle).
|
|
Item("Document 0\nSome tagline").
|
|
Item("Document 1\nHello world").
|
|
Item("Document 2\nSome other tagline"),
|
|
).
|
|
Item("Fuss")
|
|
expected := `
|
|
├── Hello
|
|
├── Foo
|
|
├── Bar
|
|
│ Document 0
|
|
│ Some tagline
|
|
│
|
|
│ │ Document 1
|
|
│ │ Hello world
|
|
│
|
|
│ Document 2
|
|
│ Some other tagline
|
|
│
|
|
└── Fuss
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestMultilinePrefixInception(t *testing.T) {
|
|
glowEnum := func(_ tree.Data, i int) (string, string) {
|
|
if i == 1 {
|
|
return " ", "│\n│"
|
|
}
|
|
return " ", " "
|
|
}
|
|
paddingsStyle := lipgloss.NewStyle().PaddingLeft(1).PaddingBottom(1)
|
|
tree := tree.New().
|
|
Enumerator(glowEnum).
|
|
ItemStyle(paddingsStyle).
|
|
Item("Document 0\nSome tagline").
|
|
Item("Document 1\nHello world").
|
|
Item(
|
|
tree.New().
|
|
Enumerator(glowEnum).
|
|
ItemStyle(paddingsStyle).
|
|
Item("Document 1a\nnothing important").
|
|
Item("Document 1b\nsomething").
|
|
Item("Document 1c\nsomething else"),
|
|
).
|
|
Item("Document 2\nSome other tagline")
|
|
expected := `
|
|
Document 0
|
|
Some tagline
|
|
|
|
│ Document 1
|
|
│ Hello world
|
|
|
|
Document 1a
|
|
nothing important
|
|
|
|
│ Document 1b
|
|
│ something
|
|
|
|
Document 1c
|
|
something else
|
|
|
|
Document 2
|
|
Some other tagline
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|
|
|
|
func TestTypes(t *testing.T) {
|
|
tree := tree.New().
|
|
Item(1).
|
|
Item(true).
|
|
Item([]any{"a", "b"}).
|
|
Item([]string{"a", "b", "c"})
|
|
expected := `
|
|
├── 1
|
|
├── true
|
|
├── a
|
|
├── b
|
|
├── a
|
|
├── b
|
|
└── c
|
|
`
|
|
require.Equal(t, expected, tree.String())
|
|
}
|