mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-25 13:48:50 +08:00
375 lines
9.6 KiB
Go
375 lines
9.6 KiB
Go
package container
|
|
|
|
import (
|
|
"image"
|
|
"testing"
|
|
|
|
"github.com/mum4k/termdash/canvas/testcanvas"
|
|
"github.com/mum4k/termdash/cell"
|
|
"github.com/mum4k/termdash/draw"
|
|
"github.com/mum4k/termdash/draw/testdraw"
|
|
"github.com/mum4k/termdash/terminal/faketerm"
|
|
"github.com/mum4k/termdash/widgetapi"
|
|
"github.com/mum4k/termdash/widgets/fakewidget"
|
|
)
|
|
|
|
func TestDrawWidget(t *testing.T) {
|
|
tests := []struct {
|
|
desc string
|
|
termSize image.Point
|
|
container func(ft *faketerm.Terminal) *Container
|
|
want func(size image.Point) *faketerm.Terminal
|
|
wantErr bool
|
|
}{
|
|
{
|
|
desc: "draws widget with container border",
|
|
termSize: image.Point{9, 5},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(1, 1, 8, 4), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{2, 2}}
|
|
testdraw.MustText(cvs, "(7,3)", tb)
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "draws widget without container border",
|
|
termSize: image.Point{9, 5},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(0, 0, 9, 5), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{1, 1}}
|
|
testdraw.MustText(cvs, "(9,5)", tb)
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "widget.Draw returns an error",
|
|
termSize: image.Point{5, 5}, // Too small for the widget's box.
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
return faketerm.MustNew(size)
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
desc: "container with border and no space isn't drawn",
|
|
termSize: image.Point{1, 1},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
testdraw.MustText(cvs, "⇄", draw.TextBounds{})
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "container without the requested space for its widget isn't drawn",
|
|
termSize: image.Point{1, 1},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
MinimumSize: image.Point{2, 2}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
testdraw.MustText(cvs, "⇄", draw.TextBounds{})
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "widget gets the requested aspect ratio",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{1, 2}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(1, 1, 11, 21), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{2, 2}}
|
|
testdraw.MustText(cvs, "(10,20)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "horizontal left align for the widget",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
HorizontalAlignLeft(),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{1, 2}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(1, 1, 11, 21), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{2, 2}}
|
|
testdraw.MustText(cvs, "(10,20)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "horizontal center align for the widget",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
HorizontalAlignCenter(),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{1, 2}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(6, 1, 16, 21), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{7, 2}}
|
|
testdraw.MustText(cvs, "(10,20)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "horizontal right align for the widget",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
HorizontalAlignRight(),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{1, 2}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(11, 1, 21, 21), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{12, 2}}
|
|
testdraw.MustText(cvs, "(10,20)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "vertical top align for the widget",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
VerticalAlignTop(),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{2, 1}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(1, 1, 21, 11), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{2, 2}}
|
|
testdraw.MustText(cvs, "(20,10)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "vertical middle align for the widget",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
VerticalAlignMiddle(),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{2, 1}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(1, 6, 21, 16), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{2, 7}}
|
|
testdraw.MustText(cvs, "(20,10)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
{
|
|
desc: "vertical bottom align for the widget",
|
|
termSize: image.Point{22, 22},
|
|
container: func(ft *faketerm.Terminal) *Container {
|
|
return New(
|
|
ft,
|
|
Border(draw.LineStyleLight),
|
|
VerticalAlignBottom(),
|
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
|
Ratio: image.Point{2, 1}},
|
|
)),
|
|
)
|
|
},
|
|
want: func(size image.Point) *faketerm.Terminal {
|
|
ft := faketerm.MustNew(size)
|
|
cvs := testcanvas.MustNew(ft.Area())
|
|
// Container border.
|
|
testdraw.MustBox(
|
|
cvs,
|
|
cvs.Area(),
|
|
draw.LineStyleLight,
|
|
cell.FgColor(cell.ColorYellow),
|
|
)
|
|
|
|
// Fake widget border.
|
|
testdraw.MustBox(cvs, image.Rect(1, 11, 21, 21), draw.LineStyleLight)
|
|
tb := draw.TextBounds{Start: image.Point{2, 12}}
|
|
testdraw.MustText(cvs, "(20,10)", tb)
|
|
|
|
testcanvas.MustApply(cvs, ft)
|
|
return ft
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
got := faketerm.MustNew(tc.termSize)
|
|
c := tc.container(got)
|
|
err := c.Draw()
|
|
if (err != nil) != tc.wantErr {
|
|
t.Errorf("Draw => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if diff := faketerm.Diff(tc.want(got.Size()), got); diff != "" {
|
|
t.Errorf("Draw => %v", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|