mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Move all components responsible for module composition into /view
This commit is contained in:
132
view/keyboard_widget.go
Normal file
132
view/keyboard_widget.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
type helpItem struct {
|
||||
Key string
|
||||
Text string
|
||||
}
|
||||
|
||||
// KeyboardWidget manages keyboard control for a widget
|
||||
type KeyboardWidget struct {
|
||||
app *tview.Application
|
||||
pages *tview.Pages
|
||||
view *tview.TextView
|
||||
settings *cfg.Common
|
||||
|
||||
charMap map[string]func()
|
||||
keyMap map[tcell.Key]func()
|
||||
charHelp []helpItem
|
||||
keyHelp []helpItem
|
||||
maxKey int
|
||||
}
|
||||
|
||||
// NewKeyboardWidget creates and returns a new instance of KeyboardWidget
|
||||
func NewKeyboardWidget(app *tview.Application, pages *tview.Pages, settings *cfg.Common) KeyboardWidget {
|
||||
return KeyboardWidget{
|
||||
app: app,
|
||||
pages: pages,
|
||||
settings: settings,
|
||||
charMap: make(map[string]func()),
|
||||
keyMap: make(map[tcell.Key]func()),
|
||||
charHelp: []helpItem{},
|
||||
keyHelp: []helpItem{},
|
||||
}
|
||||
}
|
||||
|
||||
// SetKeyboardChar sets a character/function combination that responds to key presses
|
||||
// Example:
|
||||
//
|
||||
// widget.SetKeyboardChar("d", widget.deleteSelectedItem)
|
||||
//
|
||||
func (widget *KeyboardWidget) SetKeyboardChar(char string, fn func(), helpText string) {
|
||||
if char == "" {
|
||||
return
|
||||
}
|
||||
|
||||
widget.charMap[char] = fn
|
||||
widget.charHelp = append(widget.charHelp, helpItem{char, helpText})
|
||||
}
|
||||
|
||||
// SetKeyboardKey sets a tcell.Key/function combination that responds to key presses
|
||||
// Example:
|
||||
//
|
||||
// widget.SetKeyboardKey(tcell.KeyCtrlD, widget.deleteSelectedItem)
|
||||
//
|
||||
func (widget *KeyboardWidget) SetKeyboardKey(key tcell.Key, fn func(), helpText string) {
|
||||
widget.keyMap[key] = fn
|
||||
widget.keyHelp = append(widget.keyHelp, helpItem{tcell.KeyNames[key], helpText})
|
||||
|
||||
if len(tcell.KeyNames[key]) > widget.maxKey {
|
||||
widget.maxKey = len(tcell.KeyNames[key])
|
||||
}
|
||||
}
|
||||
|
||||
// InputCapture is the function passed to tview's SetInputCapture() function
|
||||
// This is done during the main widget's creation process using the following code:
|
||||
//
|
||||
// widget.View.SetInputCapture(widget.InputCapture)
|
||||
//
|
||||
func (widget *KeyboardWidget) InputCapture(event *tcell.EventKey) *tcell.EventKey {
|
||||
if event == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
fn := widget.charMap[string(event.Rune())]
|
||||
if fn != nil {
|
||||
fn()
|
||||
return nil
|
||||
}
|
||||
|
||||
fn = widget.keyMap[event.Key()]
|
||||
if fn != nil {
|
||||
fn()
|
||||
return nil
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
// HelpText returns the help text and keyboard command info for this widget
|
||||
func (widget *KeyboardWidget) HelpText() string {
|
||||
str := " [green::b]Keyboard commands for " + strings.Title(widget.settings.Module.Type) + "[white]\n\n"
|
||||
|
||||
for _, item := range widget.charHelp {
|
||||
str += fmt.Sprintf(" %s\t%s\n", item.Key, item.Text)
|
||||
}
|
||||
str += "\n\n"
|
||||
|
||||
for _, item := range widget.keyHelp {
|
||||
str += fmt.Sprintf(" %-*s\t%s\n", widget.maxKey, item.Key, item.Text)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
func (widget *KeyboardWidget) SetView(view *tview.TextView) {
|
||||
widget.view = view
|
||||
}
|
||||
|
||||
func (widget *KeyboardWidget) ShowHelp() {
|
||||
closeFunc := func() {
|
||||
widget.pages.RemovePage("help")
|
||||
widget.app.SetFocus(widget.view)
|
||||
}
|
||||
|
||||
modal := wtf.NewBillboardModal(widget.HelpText(), closeFunc)
|
||||
|
||||
widget.pages.AddPage("help", modal, false, true)
|
||||
widget.app.SetFocus(modal)
|
||||
|
||||
widget.app.QueueUpdate(func() {
|
||||
widget.app.Draw()
|
||||
})
|
||||
}
|
||||
159
view/keyboard_widget_test.go
Normal file
159
view/keyboard_widget_test.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
func test() {}
|
||||
|
||||
func testKeyboardWidget() KeyboardWidget {
|
||||
keyWid := NewKeyboardWidget(
|
||||
tview.NewApplication(),
|
||||
tview.NewPages(),
|
||||
nil,
|
||||
)
|
||||
return keyWid
|
||||
}
|
||||
|
||||
func Test_SetKeyboardChar(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
char string
|
||||
fn func()
|
||||
helpText string
|
||||
mapChar string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "with blank char",
|
||||
char: "",
|
||||
fn: test,
|
||||
helpText: "help",
|
||||
mapChar: "",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "with undefined char",
|
||||
char: "d",
|
||||
fn: test,
|
||||
helpText: "help",
|
||||
mapChar: "m",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "with defined char",
|
||||
char: "d",
|
||||
fn: test,
|
||||
helpText: "help",
|
||||
mapChar: "d",
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
keyWid := testKeyboardWidget()
|
||||
keyWid.SetKeyboardChar(tt.char, tt.fn, tt.helpText)
|
||||
|
||||
actual := keyWid.charMap[tt.mapChar]
|
||||
|
||||
if tt.expected != (actual != nil) {
|
||||
t.Errorf("\nexpected: %s\n got: %T", "actual != nil", actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_SetKeyboardKey(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
key tcell.Key
|
||||
fn func()
|
||||
helpText string
|
||||
mapKey tcell.Key
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "with undefined key",
|
||||
key: tcell.KeyCtrlA,
|
||||
fn: test,
|
||||
helpText: "help",
|
||||
mapKey: tcell.KeyCtrlZ,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "with defined key",
|
||||
key: tcell.KeyCtrlA,
|
||||
fn: test,
|
||||
helpText: "help",
|
||||
mapKey: tcell.KeyCtrlA,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
keyWid := testKeyboardWidget()
|
||||
keyWid.SetKeyboardKey(tt.key, tt.fn, tt.helpText)
|
||||
|
||||
actual := keyWid.keyMap[tt.mapKey]
|
||||
|
||||
if tt.expected != (actual != nil) {
|
||||
t.Errorf("\nexpected: %s\n got: %T", "actual != nil", actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_InputCapture(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
before func(keyWid KeyboardWidget) KeyboardWidget
|
||||
event *tcell.EventKey
|
||||
expected *tcell.EventKey
|
||||
}{
|
||||
{
|
||||
name: "with nil event",
|
||||
before: func(keyWid KeyboardWidget) KeyboardWidget { return keyWid },
|
||||
event: nil,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "with undefined event",
|
||||
before: func(keyWid KeyboardWidget) KeyboardWidget { return keyWid },
|
||||
event: tcell.NewEventKey(tcell.KeyRune, 'a', tcell.ModNone),
|
||||
expected: tcell.NewEventKey(tcell.KeyRune, 'a', tcell.ModNone),
|
||||
},
|
||||
{
|
||||
name: "with defined event",
|
||||
before: func(keyWid KeyboardWidget) KeyboardWidget {
|
||||
keyWid.SetKeyboardChar("a", test, "help")
|
||||
return keyWid
|
||||
},
|
||||
event: tcell.NewEventKey(tcell.KeyRune, 'a', tcell.ModNone),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
keyWid := testKeyboardWidget()
|
||||
keyWid = tt.before(keyWid)
|
||||
actual := keyWid.InputCapture(tt.event)
|
||||
|
||||
if tt.expected == nil {
|
||||
if actual != nil {
|
||||
t.Errorf("\nexpected: %v\n got: %v", tt.expected, actual.Rune())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if tt.expected.Rune() != actual.Rune() {
|
||||
t.Errorf("\nexpected: %v\n got: %v", tt.expected.Rune(), actual.Rune())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
100
view/multisource_widget.go
Normal file
100
view/multisource_widget.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
// MultiSourceWidget is a widget that supports displaying data from multiple sources
|
||||
type MultiSourceWidget struct {
|
||||
moduleConfig *cfg.Common
|
||||
singular string
|
||||
plural string
|
||||
|
||||
DisplayFunction func()
|
||||
Idx int
|
||||
Sources []string
|
||||
}
|
||||
|
||||
// NewMultiSourceWidget creates and returns an instance of MultiSourceWidget
|
||||
func NewMultiSourceWidget(moduleConfig *cfg.Common, singular, plural string) MultiSourceWidget {
|
||||
widget := MultiSourceWidget{
|
||||
moduleConfig: moduleConfig,
|
||||
singular: singular,
|
||||
plural: plural,
|
||||
}
|
||||
|
||||
widget.loadSources()
|
||||
|
||||
return widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// CurrentSource returns the string representations of the currently-displayed source
|
||||
func (widget *MultiSourceWidget) CurrentSource() string {
|
||||
if widget.Idx >= len(widget.Sources) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return widget.Sources[widget.Idx]
|
||||
}
|
||||
|
||||
// NextSource displays the next source in the source list. If the current source is the last
|
||||
// source it wraps around to the first source
|
||||
func (widget *MultiSourceWidget) NextSource() {
|
||||
widget.Idx++
|
||||
if widget.Idx == len(widget.Sources) {
|
||||
widget.Idx = 0
|
||||
}
|
||||
|
||||
if widget.DisplayFunction != nil {
|
||||
widget.DisplayFunction()
|
||||
}
|
||||
}
|
||||
|
||||
// PrevSource displays the previous source in the source list. If the current source is the first
|
||||
// source, it wraps around to the last source
|
||||
func (widget *MultiSourceWidget) PrevSource() {
|
||||
widget.Idx--
|
||||
if widget.Idx < 0 {
|
||||
widget.Idx = len(widget.Sources) - 1
|
||||
}
|
||||
|
||||
if widget.DisplayFunction != nil {
|
||||
widget.DisplayFunction()
|
||||
}
|
||||
}
|
||||
|
||||
// SetDisplayFunction stores the function that should be called when the source is
|
||||
// changed. This is typically called from within the initializer for the struct that
|
||||
// embeds MultiSourceWidget
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// widget := Widget{
|
||||
// MultiSourceWidget: wtf.NewMultiSourceWidget(settings.common, "person", "people")
|
||||
// }
|
||||
//
|
||||
// widget.SetDisplayFunction(widget.display)
|
||||
//
|
||||
func (widget *MultiSourceWidget) SetDisplayFunction(displayFunc func()) {
|
||||
widget.DisplayFunction = displayFunc
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *MultiSourceWidget) loadSources() {
|
||||
var empty []interface{}
|
||||
|
||||
single := widget.moduleConfig.Config.UString(widget.singular, "")
|
||||
multiple := widget.moduleConfig.Config.UList(widget.plural, empty)
|
||||
|
||||
asStrs := wtf.ToStrs(multiple)
|
||||
|
||||
if single != "" {
|
||||
asStrs = append(asStrs, single)
|
||||
}
|
||||
|
||||
widget.Sources = asStrs
|
||||
}
|
||||
78
view/scrollable.go
Normal file
78
view/scrollable.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
)
|
||||
|
||||
type ScrollableWidget struct {
|
||||
TextWidget
|
||||
|
||||
Selected int
|
||||
maxItems int
|
||||
RenderFunction func()
|
||||
}
|
||||
|
||||
func NewScrollableWidget(app *tview.Application, commonSettings *cfg.Common, focusable bool) ScrollableWidget {
|
||||
widget := ScrollableWidget{
|
||||
TextWidget: NewTextWidget(app, commonSettings, focusable),
|
||||
}
|
||||
|
||||
widget.Unselect()
|
||||
widget.View.SetScrollable(true)
|
||||
widget.View.SetRegions(true)
|
||||
|
||||
return widget
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) SetRenderFunction(displayFunc func()) {
|
||||
widget.RenderFunction = displayFunc
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) SetItemCount(items int) {
|
||||
widget.maxItems = items
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) GetSelected() int {
|
||||
return widget.Selected
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) RowColor(idx int) string {
|
||||
if widget.View.HasFocus() && (idx == widget.Selected) {
|
||||
return widget.CommonSettings().DefaultFocusedRowColor()
|
||||
}
|
||||
|
||||
return widget.CommonSettings().RowColor(idx)
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) Next() {
|
||||
widget.Selected++
|
||||
if widget.Selected >= widget.maxItems {
|
||||
widget.Selected = 0
|
||||
}
|
||||
widget.RenderFunction()
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) Prev() {
|
||||
widget.Selected--
|
||||
if widget.Selected < 0 {
|
||||
widget.Selected = widget.maxItems - 1
|
||||
}
|
||||
widget.RenderFunction()
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) Unselect() {
|
||||
widget.Selected = -1
|
||||
if widget.RenderFunction != nil {
|
||||
widget.RenderFunction()
|
||||
}
|
||||
}
|
||||
|
||||
func (widget *ScrollableWidget) Redraw(title, content string, wrap bool) {
|
||||
widget.TextWidget.Redraw(title, content, wrap)
|
||||
widget.app.QueueUpdateDraw(func() {
|
||||
widget.View.Highlight(strconv.Itoa(widget.Selected)).ScrollToHighlight()
|
||||
})
|
||||
}
|
||||
162
view/text_widget.go
Normal file
162
view/text_widget.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
type TextWidget struct {
|
||||
bordered bool
|
||||
commonSettings *cfg.Common
|
||||
enabled bool
|
||||
focusable bool
|
||||
focusChar string
|
||||
name string
|
||||
quitChan chan bool
|
||||
refreshing bool
|
||||
refreshInterval int
|
||||
app *tview.Application
|
||||
|
||||
View *tview.TextView
|
||||
}
|
||||
|
||||
func NewTextWidget(app *tview.Application, commonSettings *cfg.Common, focusable bool) TextWidget {
|
||||
widget := TextWidget{
|
||||
commonSettings: commonSettings,
|
||||
|
||||
app: app,
|
||||
bordered: commonSettings.Bordered,
|
||||
enabled: commonSettings.Enabled,
|
||||
focusable: focusable,
|
||||
focusChar: commonSettings.FocusChar(),
|
||||
name: commonSettings.Name,
|
||||
quitChan: make(chan bool),
|
||||
refreshing: false,
|
||||
refreshInterval: commonSettings.RefreshInterval,
|
||||
}
|
||||
|
||||
widget.View = widget.addView()
|
||||
widget.View.SetBorder(widget.bordered)
|
||||
|
||||
return widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// Bordered returns whether or not this widget should be drawn with a border
|
||||
func (widget *TextWidget) Bordered() bool {
|
||||
return widget.bordered
|
||||
}
|
||||
|
||||
func (widget *TextWidget) BorderColor() string {
|
||||
if widget.Focusable() {
|
||||
return widget.commonSettings.Colors.BorderFocusable
|
||||
}
|
||||
|
||||
return widget.commonSettings.Colors.BorderNormal
|
||||
}
|
||||
|
||||
func (widget *TextWidget) CommonSettings() *cfg.Common {
|
||||
return widget.commonSettings
|
||||
}
|
||||
|
||||
func (widget *TextWidget) ConfigText() string {
|
||||
return utils.HelpFromInterface(cfg.Common{})
|
||||
}
|
||||
|
||||
func (widget *TextWidget) ContextualTitle(defaultStr string) string {
|
||||
if widget.FocusChar() == "" {
|
||||
return fmt.Sprintf(" %s ", defaultStr)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(" %s [darkgray::u]%s[::-][green] ", defaultStr, widget.FocusChar())
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Disable() {
|
||||
widget.enabled = false
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Disabled() bool {
|
||||
return !widget.Enabled()
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Enabled() bool {
|
||||
return widget.enabled
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Focusable() bool {
|
||||
return widget.enabled && widget.focusable
|
||||
}
|
||||
|
||||
func (widget *TextWidget) FocusChar() string {
|
||||
return widget.focusChar
|
||||
}
|
||||
|
||||
func (widget *TextWidget) HelpText() string {
|
||||
return fmt.Sprintf("\n There is no help available for widget %s", widget.commonSettings.Module.Type)
|
||||
}
|
||||
|
||||
func (widget *TextWidget) QuitChan() chan bool {
|
||||
return widget.quitChan
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Name() string {
|
||||
return widget.name
|
||||
}
|
||||
|
||||
// Refreshing returns TRUE if the widget is currently refreshing its data, FALSE if it is not
|
||||
func (widget *TextWidget) Refreshing() bool {
|
||||
return widget.refreshing
|
||||
}
|
||||
|
||||
// RefreshInterval returns how often, in seconds, the widget will return its data
|
||||
func (widget *TextWidget) RefreshInterval() int {
|
||||
return widget.refreshInterval
|
||||
}
|
||||
|
||||
func (widget *TextWidget) SetFocusChar(char string) {
|
||||
widget.focusChar = char
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Stop() {
|
||||
widget.enabled = false
|
||||
widget.quitChan <- true
|
||||
}
|
||||
|
||||
func (widget *TextWidget) String() string {
|
||||
return widget.name
|
||||
}
|
||||
|
||||
func (widget *TextWidget) TextView() *tview.TextView {
|
||||
return widget.View
|
||||
}
|
||||
|
||||
func (widget *TextWidget) Redraw(title, text string, wrap bool) {
|
||||
widget.app.QueueUpdateDraw(func() {
|
||||
widget.View.Clear()
|
||||
widget.View.SetWrap(wrap)
|
||||
widget.View.SetTitle(widget.ContextualTitle(title))
|
||||
widget.View.SetText(text)
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *TextWidget) addView() *tview.TextView {
|
||||
view := tview.NewTextView()
|
||||
|
||||
view.SetBackgroundColor(wtf.ColorFor(widget.commonSettings.Colors.Background))
|
||||
view.SetBorderColor(wtf.ColorFor(widget.BorderColor()))
|
||||
view.SetTextColor(wtf.ColorFor(widget.commonSettings.Colors.Text))
|
||||
view.SetTitleColor(wtf.ColorFor(widget.commonSettings.Colors.Title))
|
||||
|
||||
view.SetBorder(true)
|
||||
view.SetDynamicColors(true)
|
||||
view.SetWrap(false)
|
||||
|
||||
return view
|
||||
}
|
||||
209
view/text_widget_test.go
Normal file
209
view/text_widget_test.go
Normal file
@@ -0,0 +1,209 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/cfg"
|
||||
)
|
||||
|
||||
func testTextWidget() TextWidget {
|
||||
txtWid := NewTextWidget(
|
||||
tview.NewApplication(),
|
||||
&cfg.Common{
|
||||
Module: cfg.Module{
|
||||
Name: "test widget",
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
return txtWid
|
||||
}
|
||||
|
||||
func Test_Bordered(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
before func(txtWid TextWidget) TextWidget
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "without border",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.bordered = false
|
||||
return txtWid
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "with border",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.bordered = true
|
||||
return txtWid
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
txtWid := testTextWidget()
|
||||
txtWid = tt.before(txtWid)
|
||||
actual := txtWid.Bordered()
|
||||
|
||||
if tt.expected != actual {
|
||||
t.Errorf("\nexpected: %t\n got: %t", tt.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Disabled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
before func(txtWid TextWidget) TextWidget
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "when not enabled",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = false
|
||||
return txtWid
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "when enabled",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = true
|
||||
return txtWid
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
txtWid := testTextWidget()
|
||||
txtWid = tt.before(txtWid)
|
||||
actual := txtWid.Disabled()
|
||||
|
||||
if tt.expected != actual {
|
||||
t.Errorf("\nexpected: %t\n got: %t", tt.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Enabled(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
before func(txtWid TextWidget) TextWidget
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "when not enabled",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = false
|
||||
return txtWid
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "when enabled",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = true
|
||||
return txtWid
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
txtWid := testTextWidget()
|
||||
txtWid = tt.before(txtWid)
|
||||
actual := txtWid.Enabled()
|
||||
|
||||
if tt.expected != actual {
|
||||
t.Errorf("\nexpected: %t\n got: %t", tt.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Focusable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
before func(txtWid TextWidget) TextWidget
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "when not focusable",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = false
|
||||
txtWid.focusable = false
|
||||
return txtWid
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "when not focusable",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = false
|
||||
txtWid.focusable = true
|
||||
return txtWid
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "when not focusable",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = true
|
||||
txtWid.focusable = false
|
||||
return txtWid
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "when focusable",
|
||||
before: func(txtWid TextWidget) TextWidget {
|
||||
txtWid.enabled = true
|
||||
txtWid.focusable = true
|
||||
return txtWid
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
txtWid := testTextWidget()
|
||||
txtWid = tt.before(txtWid)
|
||||
actual := txtWid.Focusable()
|
||||
|
||||
if tt.expected != actual {
|
||||
t.Errorf("\nexpected: %t\n got: %t", tt.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Name(t *testing.T) {
|
||||
txtWid := testTextWidget()
|
||||
actual := txtWid.Name()
|
||||
expected := "test widget"
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\n got: %s", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_String(t *testing.T) {
|
||||
txtWid := testTextWidget()
|
||||
actual := txtWid.String()
|
||||
expected := "test widget"
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\n got: %s", expected, actual)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user