mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
WTF-657 Add spec coverage for cfg/common_settings.go (#728)
* WTF-657 Add spec coverage for cfg/common_settings.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for cfg/position_validation.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for cfg/validations.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for checklist/checklist.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for checklist/checklist_item.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for utils/conversions.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Get rid of utils.Home() function Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for utils/homedir.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Add spec coverage for utils/text.go Signed-off-by: Chris Cummer <chriscummer@me.com> * WTF-657 Clean up utils/utils.go Signed-off-by: Chris Cummer <chriscummer@me.com>
This commit is contained in:
parent
837dc92cfc
commit
1bfca29d17
6
Makefile
6
Makefile
@ -1,4 +1,4 @@
|
||||
.PHONY: build contrib_check install binary_msg lint run size test uninstall
|
||||
.PHONY: build contrib_check coverage install binary_msg lint run size test uninstall
|
||||
|
||||
# detect GOPATH if not set
|
||||
ifndef $(GOPATH)
|
||||
@ -30,6 +30,10 @@ build:
|
||||
contrib_check:
|
||||
npx all-contributors-cli check
|
||||
|
||||
coverage:
|
||||
go test -coverprofile=coverage.out ./...
|
||||
go tool cover -html=coverage.out
|
||||
|
||||
install:
|
||||
@echo "Installing wtfutil..."
|
||||
@go clean
|
||||
|
@ -14,8 +14,8 @@ type Colors struct {
|
||||
BorderNormal string
|
||||
Checked string
|
||||
Foreground string
|
||||
HighlightFore string
|
||||
HighlightBack string
|
||||
HighlightFore string
|
||||
Text string
|
||||
Title string
|
||||
|
||||
@ -83,11 +83,11 @@ func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable boo
|
||||
PositionSettings: NewPositionSettingsFromYAML(name, moduleConfig),
|
||||
|
||||
Bordered: moduleConfig.UBool("border", true),
|
||||
Config: moduleConfig,
|
||||
Enabled: moduleConfig.UBool("enabled", false),
|
||||
Focusable: moduleConfig.UBool("focusable", defaultFocusable),
|
||||
RefreshInterval: moduleConfig.UInt("refreshInterval", 300),
|
||||
Title: moduleConfig.UString("title", defaultTitle),
|
||||
Config: moduleConfig,
|
||||
|
||||
focusChar: moduleConfig.UInt("focusChar", -1),
|
||||
}
|
||||
@ -135,7 +135,7 @@ func (common *Common) RightAlignFormat(width int) string {
|
||||
return fmt.Sprintf("%%%ds", width-borderOffset)
|
||||
}
|
||||
|
||||
func (common *Common) SigilStr(len, pos int, width int) string {
|
||||
func (common *Common) SigilStr(len, pos, width int) string {
|
||||
sigils := ""
|
||||
|
||||
if len > 1 {
|
||||
|
187
cfg/common_settings_test.go
Normal file
187
cfg/common_settings_test.go
Normal file
@ -0,0 +1,187 @@
|
||||
package cfg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/olebedev/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
testYaml = `
|
||||
wtf:
|
||||
colors:
|
||||
`
|
||||
|
||||
moduleConfig, _ = config.ParseYaml(testYaml)
|
||||
globalSettings, _ = config.ParseYaml(testYaml)
|
||||
|
||||
testCfg = NewCommonSettingsFromModule(
|
||||
"test",
|
||||
"Test Config",
|
||||
true,
|
||||
moduleConfig,
|
||||
globalSettings,
|
||||
)
|
||||
)
|
||||
|
||||
func Test_NewCommonSettingsFromModule(t *testing.T) {
|
||||
assert.Equal(t, true, testCfg.Bordered)
|
||||
assert.Equal(t, false, testCfg.Enabled)
|
||||
assert.Equal(t, true, testCfg.Focusable)
|
||||
assert.Equal(t, "test", testCfg.Module.Name)
|
||||
assert.Equal(t, "test", testCfg.Module.Type)
|
||||
assert.Equal(t, "", testCfg.FocusChar())
|
||||
assert.Equal(t, 300, testCfg.RefreshInterval)
|
||||
assert.Equal(t, "Test Config", testCfg.Title)
|
||||
}
|
||||
|
||||
func Test_DefaultFocusedRowColor(t *testing.T) {
|
||||
assert.Equal(t, "black:green", testCfg.DefaultFocusedRowColor())
|
||||
}
|
||||
|
||||
func Test_DefaultRowColor(t *testing.T) {
|
||||
assert.Equal(t, "white:transparent", testCfg.DefaultRowColor())
|
||||
}
|
||||
|
||||
func Test_FocusChar(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedChar string
|
||||
before func(testCfg *Common)
|
||||
}{
|
||||
{
|
||||
name: "with no focus char specified",
|
||||
expectedChar: "",
|
||||
before: func(testCfg *Common) {
|
||||
testCfg.focusChar = -1
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with explicit focus char specified",
|
||||
expectedChar: "3",
|
||||
before: func(testCfg *Common) {
|
||||
testCfg.focusChar = 3
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with ridiculous focus char specified",
|
||||
expectedChar: "Q",
|
||||
before: func(testCfg *Common) {
|
||||
testCfg.focusChar = 33
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.before(testCfg)
|
||||
|
||||
assert.Equal(t, tt.expectedChar, testCfg.FocusChar())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_RowColor(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
idx int
|
||||
expectedColor string
|
||||
}{
|
||||
{
|
||||
name: "odd rows, default",
|
||||
idx: 3,
|
||||
expectedColor: "lightblue",
|
||||
},
|
||||
{
|
||||
name: "even rows, default",
|
||||
idx: 8,
|
||||
expectedColor: "white",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expectedColor, testCfg.RowColor(tt.idx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_RightAlignFormat(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
width int
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "with zero",
|
||||
width: 0,
|
||||
expected: "%-2s",
|
||||
},
|
||||
{
|
||||
name: "with positive integer",
|
||||
width: 3,
|
||||
expected: "%1s",
|
||||
},
|
||||
{
|
||||
name: "with negative integer",
|
||||
width: -3,
|
||||
expected: "%-5s",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, testCfg.RightAlignFormat(tt.width))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_SigilStr(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
len int
|
||||
pos int
|
||||
width int
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "with zero pages",
|
||||
len: 0,
|
||||
pos: 1,
|
||||
width: 5,
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "with one page",
|
||||
len: 1,
|
||||
pos: 1,
|
||||
width: 5,
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "with multiple pages",
|
||||
len: 3,
|
||||
pos: 1,
|
||||
width: 5,
|
||||
expected: "[lightblue]*_*[white]",
|
||||
},
|
||||
{
|
||||
name: "with negative pages",
|
||||
len: -3,
|
||||
pos: 1,
|
||||
width: 5,
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, testCfg.SigilStr(tt.len, tt.pos, tt.width))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Validations(t *testing.T) {
|
||||
assert.Equal(t, 4, len(testCfg.Validations()))
|
||||
}
|
14
cfg/error_messages_test.go
Normal file
14
cfg/error_messages_test.go
Normal file
@ -0,0 +1,14 @@
|
||||
package cfg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
errTest = errors.New("Busted")
|
||||
)
|
||||
|
||||
func ExampleDisplayError() {
|
||||
displayError(errTest)
|
||||
// Output: [31mError:[0m Busted
|
||||
}
|
@ -41,10 +41,10 @@ func NewPositionSettingsFromYAML(moduleName string, moduleConfig *config.Config)
|
||||
pos := PositionSettings{
|
||||
Validations: validations,
|
||||
|
||||
Top: validations.valueFor("top"),
|
||||
Left: validations.valueFor("left"),
|
||||
Width: validations.valueFor("width"),
|
||||
Height: validations.valueFor("height"),
|
||||
Top: validations.intValueFor("top"),
|
||||
Left: validations.intValueFor("left"),
|
||||
Width: validations.intValueFor("width"),
|
||||
Height: validations.intValueFor("height"),
|
||||
}
|
||||
|
||||
return pos
|
||||
|
@ -54,6 +54,8 @@ func (posVal *positionValidation) String() string {
|
||||
return fmt.Sprintf("Invalid value for %s:\t%d", aurora.Yellow(posVal.name), posVal.intVal)
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func newPositionValidation(name string, intVal int, err error) *positionValidation {
|
||||
posVal := &positionValidation{
|
||||
err: err,
|
||||
|
26
cfg/position_validation_test.go
Normal file
26
cfg/position_validation_test.go
Normal file
@ -0,0 +1,26 @@
|
||||
package cfg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/alecthomas/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
posVal = &positionValidation{
|
||||
err: errors.New("Busted"),
|
||||
name: "top",
|
||||
intVal: -3,
|
||||
}
|
||||
)
|
||||
|
||||
func Test_Attributes(t *testing.T) {
|
||||
assert.EqualError(t, posVal.Error(), "Busted")
|
||||
assert.Equal(t, true, posVal.HasError())
|
||||
assert.Equal(t, -3, posVal.IntValue())
|
||||
|
||||
assert.Contains(t, posVal.String(), "Invalid")
|
||||
assert.Contains(t, posVal.String(), "top")
|
||||
assert.Contains(t, posVal.String(), "-3")
|
||||
}
|
@ -18,7 +18,7 @@ func (vals *Validations) append(key string, posVal Validatable) {
|
||||
vals.validations[key] = posVal
|
||||
}
|
||||
|
||||
func (vals *Validations) valueFor(key string) int {
|
||||
func (vals *Validations) intValueFor(key string) int {
|
||||
val := vals.validations[key]
|
||||
if val != nil {
|
||||
return val.IntValue()
|
||||
|
38
cfg/validations_test.go
Normal file
38
cfg/validations_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
package cfg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
vals = NewValidations()
|
||||
)
|
||||
|
||||
func Test_intValueFor(t *testing.T) {
|
||||
vals.append("left", newPositionValidation("left", 3, nil))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
key string
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
name: "with valid key",
|
||||
key: "left",
|
||||
expected: 3,
|
||||
},
|
||||
{
|
||||
name: "with invalid key",
|
||||
key: "cat",
|
||||
expected: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, vals.intValueFor(tt.key))
|
||||
})
|
||||
}
|
||||
}
|
@ -22,7 +22,8 @@ func NewChecklist(checkedIcon, uncheckedIcon string) Checklist {
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// Add creates a new item in the checklist
|
||||
// Add creates a new checklist item and prepends it onto the existing
|
||||
// list of items. The new one is at the start of the list
|
||||
func (list *Checklist) Add(checked bool, text string) {
|
||||
item := NewChecklistItem(
|
||||
checked,
|
||||
@ -49,8 +50,10 @@ func (list *Checklist) CheckedItems() []*ChecklistItem {
|
||||
|
||||
// Delete removes the selected item from the checklist
|
||||
func (list *Checklist) Delete(selectedIndex int) {
|
||||
if selectedIndex >= 0 && selectedIndex < len(list.Items) {
|
||||
list.Items = append(list.Items[:selectedIndex], list.Items[selectedIndex+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
// IsSelectable returns true if the checklist has selectable items, false if it does not
|
||||
func (list *Checklist) IsSelectable() bool {
|
||||
|
@ -10,7 +10,7 @@ func testChecklistItem() *ChecklistItem {
|
||||
item := NewChecklistItem(
|
||||
false,
|
||||
"test",
|
||||
"x",
|
||||
"",
|
||||
"",
|
||||
)
|
||||
return item
|
||||
|
436
checklist/checklist_test.go
Normal file
436
checklist/checklist_test.go
Normal file
@ -0,0 +1,436 @@
|
||||
package checklist
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_NewCheckist(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
|
||||
assert.IsType(t, Checklist{}, cl)
|
||||
assert.Equal(t, "o", cl.checkedIcon)
|
||||
assert.Equal(t, -1, cl.selected)
|
||||
assert.Equal(t, "-", cl.uncheckedIcon)
|
||||
assert.Equal(t, 0, len(cl.Items))
|
||||
}
|
||||
|
||||
func Test_Add(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(true, "test item")
|
||||
|
||||
assert.Equal(t, 1, len(cl.Items))
|
||||
}
|
||||
|
||||
func Test_CheckedItems(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLen int
|
||||
checkedLen int
|
||||
before func(cl *Checklist)
|
||||
}{
|
||||
{
|
||||
name: "with no items",
|
||||
expectedLen: 0,
|
||||
checkedLen: 0,
|
||||
before: func(cl *Checklist) {},
|
||||
},
|
||||
{
|
||||
name: "with no checked items",
|
||||
expectedLen: 1,
|
||||
checkedLen: 0,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with one checked item",
|
||||
expectedLen: 2,
|
||||
checkedLen: 1,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
cl.Add(true, "checked item")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with multiple checked items",
|
||||
expectedLen: 3,
|
||||
checkedLen: 2,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
cl.Add(true, "checked item 11")
|
||||
cl.Add(true, "checked item 2")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
tt.before(&cl)
|
||||
|
||||
assert.Equal(t, tt.expectedLen, len(cl.Items))
|
||||
assert.Equal(t, tt.checkedLen, len(cl.CheckedItems()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Delete(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
idx int
|
||||
expectedLen int
|
||||
}{
|
||||
{
|
||||
name: "with valid index",
|
||||
idx: 0,
|
||||
expectedLen: 0,
|
||||
},
|
||||
{
|
||||
name: "with invalid index",
|
||||
idx: 2,
|
||||
expectedLen: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
|
||||
cl.Add(true, "test item")
|
||||
cl.Delete(tt.idx)
|
||||
|
||||
assert.Equal(t, tt.expectedLen, len(cl.Items))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IsSelectable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
selected int
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "nothing selected",
|
||||
selected: -1,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "valid selection",
|
||||
selected: 1,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "invalid selection",
|
||||
selected: 3,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(true, "test item 1")
|
||||
cl.Add(false, "test item 2")
|
||||
|
||||
cl.selected = tt.selected
|
||||
|
||||
assert.Equal(t, tt.expected, cl.IsSelectable())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IsUnselectable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
selected int
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "nothing selected",
|
||||
selected: -1,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "valid selection",
|
||||
selected: 1,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid selection",
|
||||
selected: 3,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(true, "test item 1")
|
||||
cl.Add(false, "test item 2")
|
||||
|
||||
cl.selected = tt.selected
|
||||
|
||||
assert.Equal(t, tt.expected, cl.IsUnselectable())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_LongestLine(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLen int
|
||||
before func(cl *Checklist)
|
||||
}{
|
||||
{
|
||||
name: "with no items",
|
||||
expectedLen: 0,
|
||||
before: func(cl *Checklist) {},
|
||||
},
|
||||
{
|
||||
name: "with different-length items",
|
||||
expectedLen: 12,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(true, "test item 1")
|
||||
cl.Add(false, "test item 22")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with same-length items",
|
||||
expectedLen: 11,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(true, "test item 1")
|
||||
cl.Add(false, "test item 2")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
tt.before(&cl)
|
||||
|
||||
assert.Equal(t, tt.expectedLen, cl.LongestLine())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_IndexByItem(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(false, "unchecked item")
|
||||
cl.Add(true, "checked item")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
item *ChecklistItem
|
||||
expectedIdx int
|
||||
expectedOk bool
|
||||
}{
|
||||
{
|
||||
name: "with nil",
|
||||
item: nil,
|
||||
expectedIdx: 0,
|
||||
expectedOk: false,
|
||||
},
|
||||
{
|
||||
name: "with valid item",
|
||||
item: cl.Items[1],
|
||||
expectedIdx: 1,
|
||||
expectedOk: true,
|
||||
},
|
||||
{
|
||||
name: "with valid item",
|
||||
item: NewChecklistItem(false, "invalid", "x", " "),
|
||||
expectedIdx: 0,
|
||||
expectedOk: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
idx, ok := cl.IndexByItem(tt.item)
|
||||
|
||||
assert.Equal(t, tt.expectedIdx, idx)
|
||||
assert.Equal(t, tt.expectedOk, ok)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_UncheckedItems(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLen int
|
||||
checkedLen int
|
||||
before func(cl *Checklist)
|
||||
}{
|
||||
{
|
||||
name: "with no items",
|
||||
expectedLen: 0,
|
||||
checkedLen: 0,
|
||||
before: func(cl *Checklist) {},
|
||||
},
|
||||
{
|
||||
name: "with no unchecked items",
|
||||
expectedLen: 1,
|
||||
checkedLen: 0,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(true, "unchecked item")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with one unchecked item",
|
||||
expectedLen: 2,
|
||||
checkedLen: 1,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
cl.Add(true, "checked item")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with multiple unchecked items",
|
||||
expectedLen: 3,
|
||||
checkedLen: 2,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
cl.Add(true, "checked item 11")
|
||||
cl.Add(false, "checked item 2")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
tt.before(&cl)
|
||||
|
||||
assert.Equal(t, tt.expectedLen, len(cl.Items))
|
||||
assert.Equal(t, tt.checkedLen, len(cl.UncheckedItems()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Unselect(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(false, "unchecked item")
|
||||
|
||||
cl.selected = 0
|
||||
assert.Equal(t, 0, cl.selected)
|
||||
|
||||
cl.Unselect()
|
||||
assert.Equal(t, -1, cl.selected)
|
||||
}
|
||||
|
||||
/* -------------------- Sort Interface -------------------- */
|
||||
|
||||
func Test_Len(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expectedLen int
|
||||
before func(cl *Checklist)
|
||||
}{
|
||||
{
|
||||
name: "with no items",
|
||||
expectedLen: 0,
|
||||
before: func(cl *Checklist) {},
|
||||
},
|
||||
{
|
||||
name: "with one item",
|
||||
expectedLen: 1,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with multiple items",
|
||||
expectedLen: 3,
|
||||
before: func(cl *Checklist) {
|
||||
cl.Add(false, "unchecked item")
|
||||
cl.Add(true, "checked item 1")
|
||||
cl.Add(false, "checked item 2")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
tt.before(&cl)
|
||||
|
||||
assert.Equal(t, tt.expectedLen, cl.Len())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Less(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
first string
|
||||
second string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "same",
|
||||
first: "",
|
||||
second: "",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "last less",
|
||||
first: "beta",
|
||||
second: "alpha",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "first less",
|
||||
first: "alpha",
|
||||
second: "beta",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(false, tt.first)
|
||||
cl.Add(false, tt.second)
|
||||
|
||||
assert.Equal(t, tt.expected, cl.Less(0, 1))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Swap(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
first string
|
||||
second string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "same",
|
||||
first: "",
|
||||
second: "",
|
||||
},
|
||||
{
|
||||
name: "last less",
|
||||
first: "alpha",
|
||||
second: "beta",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cl := NewChecklist("o", "-")
|
||||
cl.Add(false, tt.first)
|
||||
cl.Add(false, tt.second)
|
||||
|
||||
cl.Swap(0, 1)
|
||||
|
||||
assert.Equal(t, tt.expected, cl.Items[0].Text == "beta")
|
||||
assert.Equal(t, tt.expected, cl.Items[1].Text == "alpha")
|
||||
})
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@ import (
|
||||
goFlags "github.com/jessevdk/go-flags"
|
||||
"github.com/olebedev/config"
|
||||
"github.com/wtfutil/wtf/help"
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
)
|
||||
|
||||
// Flags is the container for command line flag data
|
||||
@ -80,7 +79,7 @@ func (flags *Flags) Parse() {
|
||||
}
|
||||
|
||||
// If no config file is explicitly passed in as a param then set the flag to the default config file
|
||||
homeDir, err := utils.Home()
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
1
go.mod
1
go.mod
@ -10,6 +10,7 @@ require (
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/VictorAvelar/devto-api-go v1.0.0
|
||||
github.com/adlio/trello v1.4.0
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
|
||||
github.com/alecthomas/chroma v0.6.8
|
||||
github.com/andygrunwald/go-gerrit v0.0.0-20190825170856-5959a9bf9ff8
|
||||
github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d
|
||||
|
@ -4,8 +4,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
)
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
@ -30,7 +28,7 @@ func LogFileMissing() bool {
|
||||
}
|
||||
|
||||
func LogFilePath() string {
|
||||
dir, err := utils.Home()
|
||||
dir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -2,8 +2,9 @@ package buildkite
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/wtfutil/wtf/utils"
|
||||
)
|
||||
|
||||
type Pipeline struct {
|
||||
@ -61,7 +62,7 @@ func (widget *Widget) recentBuilds(pipeline PipelineSettings) ([]Build, error) {
|
||||
}
|
||||
|
||||
builds := []Build{}
|
||||
err = utils.ParseJson(&builds, resp.Body)
|
||||
err = utils.ParseJSON(&builds, resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func (client *Client) BuildsFor() ([]*Build, error) {
|
||||
return builds, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&builds, resp.Body)
|
||||
err = utils.ParseJSON(&builds, resp.Body)
|
||||
if err != nil {
|
||||
return builds, err
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ func GetMessages(roomId string, numberOfMessages int, apiToken string) ([]Messag
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&messages, resp.Body)
|
||||
err = utils.ParseJSON(&messages, resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -32,7 +32,7 @@ func GetRoom(roomUri, apiToken string) (*Room, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&rooms, resp.Body)
|
||||
err = utils.ParseJSON(&rooms, resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func GetStories(storyType string) ([]int, error) {
|
||||
return storyIds, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&storyIds, resp.Body)
|
||||
err = utils.ParseJSON(&storyIds, resp.Body)
|
||||
if err != nil {
|
||||
return storyIds, err
|
||||
}
|
||||
@ -36,7 +36,7 @@ func GetStory(id int) (Story, error) {
|
||||
return story, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&story, resp.Body)
|
||||
err = utils.ParseJSON(&story, resp.Body)
|
||||
if err != nil {
|
||||
return story, err
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (widget *Widget) Create(jenkinsURL string, username string, apiKey string)
|
||||
return view, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(view, resp.Body)
|
||||
err = utils.ParseJSON(view, resp.Body)
|
||||
if err != nil {
|
||||
return view, err
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (widget *Widget) IssuesFor(username string, projects []string, jql string)
|
||||
}
|
||||
|
||||
searchResult := &SearchResult{}
|
||||
err = utils.ParseJson(searchResult, resp.Body)
|
||||
err = utils.ParseJSON(searchResult, resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ func Test_generateTitle(t *testing.T) {
|
||||
title string
|
||||
namespaces []string
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
fields fields
|
||||
@ -46,6 +47,7 @@ func Test_generateTitle(t *testing.T) {
|
||||
want: "Test Explicit Title",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
widget := &Widget{
|
||||
|
@ -18,7 +18,7 @@ func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*A
|
||||
return items, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&items, resp.Body)
|
||||
err = utils.ParseJSON(&items, resp.Body)
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ func GetLinks(subreddit string, sortMode string, topTimePeriod string) ([]Link,
|
||||
return nil, fmt.Errorf(resp.Status)
|
||||
}
|
||||
var m RedditDocument
|
||||
err = utils.ParseJson(&m, resp.Body)
|
||||
err = utils.ParseJSON(&m, resp.Body)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -26,7 +26,7 @@ func BuildsFor(settings *Settings) (*Builds, error) {
|
||||
return builds, err
|
||||
}
|
||||
|
||||
err = utils.ParseJson(&builds, resp.Body)
|
||||
err = utils.ParseJSON(&builds, resp.Body)
|
||||
if err != nil {
|
||||
return builds, err
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package utils
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_MapToStrs(t *testing.T) {
|
||||
@ -18,7 +18,7 @@ func Test_MapToStrs(t *testing.T) {
|
||||
source[val] = val
|
||||
}
|
||||
|
||||
Equal(t, expected, MapToStrs(source))
|
||||
assert.Equal(t, expected, MapToStrs(source))
|
||||
}
|
||||
|
||||
func Test_ToInts(t *testing.T) {
|
||||
@ -29,16 +29,23 @@ func Test_ToInts(t *testing.T) {
|
||||
source[idx] = val
|
||||
}
|
||||
|
||||
Equal(t, expected, ToInts(source))
|
||||
assert.Equal(t, expected, ToInts(source))
|
||||
}
|
||||
|
||||
func Test_ToStrs(t *testing.T) {
|
||||
expected := []string{"cat", "dog", "rat"}
|
||||
expectedInts := []int{1, 2, 3}
|
||||
expectedStrs := []string{"1", "2", "3"}
|
||||
|
||||
source := make([]interface{}, len(expected))
|
||||
for idx, val := range expected {
|
||||
source[idx] = val
|
||||
fromInts := make([]interface{}, 3)
|
||||
for idx, val := range expectedInts {
|
||||
fromInts[idx] = val
|
||||
}
|
||||
|
||||
Equal(t, expected, ToStrs(source))
|
||||
fromStrs := make([]interface{}, 3)
|
||||
for idx, val := range expectedStrs {
|
||||
fromStrs[idx] = val
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedStrs, ToStrs(fromInts))
|
||||
assert.Equal(t, expectedStrs, ToStrs(fromStrs))
|
||||
}
|
||||
|
@ -26,16 +26,10 @@ func ExpandHomeDir(path string) (string, error) {
|
||||
return "", errors.New("cannot expand user-specific home dir")
|
||||
}
|
||||
|
||||
dir, err := Home()
|
||||
dir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filepath.Join(dir, path[1:]), nil
|
||||
}
|
||||
|
||||
// Home returns the home directory for the executing user.
|
||||
// An error is returned if a home directory cannot be detected.
|
||||
func Home() (string, error) {
|
||||
return os.UserHomeDir()
|
||||
}
|
||||
|
52
utils/homedir_test.go
Normal file
52
utils/homedir_test.go
Normal file
@ -0,0 +1,52 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_ExpandHomeDir(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expectedStart string
|
||||
expectedContains string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
name: "with empty path",
|
||||
path: "",
|
||||
expectedStart: "",
|
||||
expectedContains: "",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "with relative path",
|
||||
path: "~/test",
|
||||
expectedStart: "/",
|
||||
expectedContains: "/test",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "with absolute path",
|
||||
path: "/Users/test",
|
||||
expectedStart: "/",
|
||||
expectedContains: "/test",
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual, err := ExpandHomeDir(tt.path)
|
||||
|
||||
if len(tt.path) > 0 {
|
||||
assert.Equal(t, tt.expectedStart, string(actual[0]))
|
||||
}
|
||||
|
||||
assert.Contains(t, actual, tt.expectedContains)
|
||||
assert.Equal(t, tt.expectedError, err)
|
||||
})
|
||||
}
|
||||
}
|
@ -3,18 +3,26 @@ package utils
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/stretchr/testify/assert"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_CenterText(t *testing.T) {
|
||||
Equal(t, "cat", CenterText("cat", -9))
|
||||
Equal(t, "cat", CenterText("cat", 0))
|
||||
Equal(t, " cat ", CenterText("cat", 9))
|
||||
assert.Equal(t, "cat", CenterText("cat", -9))
|
||||
assert.Equal(t, "cat", CenterText("cat", 0))
|
||||
assert.Equal(t, " cat ", CenterText("cat", 9))
|
||||
}
|
||||
|
||||
func Test_HighlightableHelper(t *testing.T) {
|
||||
view := tview.NewTextView()
|
||||
actual := HighlightableHelper(view, "cats", 0, 5)
|
||||
|
||||
assert.Equal(t, "[\"0\"][\"\"]cats [\"\"]\n", actual)
|
||||
}
|
||||
|
||||
func Test_RowPadding(t *testing.T) {
|
||||
Equal(t, "", RowPadding(0, 0))
|
||||
Equal(t, "", RowPadding(5, 2))
|
||||
Equal(t, " ", RowPadding(1, 2))
|
||||
Equal(t, " ", RowPadding(0, 5))
|
||||
assert.Equal(t, "", RowPadding(0, 0))
|
||||
assert.Equal(t, "", RowPadding(5, 2))
|
||||
assert.Equal(t, " ", RowPadding(1, 2))
|
||||
assert.Equal(t, " ", RowPadding(0, 5))
|
||||
}
|
||||
|
@ -121,8 +121,8 @@ func ReadFileBytes(filePath string) ([]byte, error) {
|
||||
return fileData, nil
|
||||
}
|
||||
|
||||
// ParseJson is a standard JSON reader from text
|
||||
func ParseJson(obj interface{}, text io.Reader) error {
|
||||
// ParseJSON is a standard JSON reader from text
|
||||
func ParseJSON(obj interface{}, text io.Reader) error {
|
||||
d := json.NewDecoder(text)
|
||||
return d.Decode(obj)
|
||||
}
|
||||
@ -139,10 +139,10 @@ func CalculateDimensions(moduleConfig, globalConfig *config.Config) (int, int) {
|
||||
rows := ToInts(globalConfig.UList("wtf.grid.rows"))
|
||||
|
||||
// Make sure the values are in bounds
|
||||
left = clamp(left, 0, len(cols)-1)
|
||||
top = clamp(top, 0, len(rows)-1)
|
||||
width = clamp(width, 0, len(cols)-left)
|
||||
height = clamp(height, 0, len(rows)-top)
|
||||
left = Clamp(left, 0, len(cols)-1)
|
||||
top = Clamp(top, 0, len(rows)-1)
|
||||
width = Clamp(width, 0, len(cols)-left)
|
||||
height = Clamp(height, 0, len(rows)-top)
|
||||
|
||||
// Start with the border subtracted and add all the spanned rows and cols
|
||||
w, h := -2, -2
|
||||
@ -154,20 +154,35 @@ func CalculateDimensions(moduleConfig, globalConfig *config.Config) (int, int) {
|
||||
}
|
||||
|
||||
// The usable space may be empty
|
||||
w = max(w, 0)
|
||||
h = max(h, 0)
|
||||
w = MaxInt(w, 0)
|
||||
h = MaxInt(h, 0)
|
||||
|
||||
return w, h
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
// MaxInt returns the larger of x or y
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// MaxInt(3, 2) => 3
|
||||
// MaxInt(2, 3) => 3
|
||||
//
|
||||
func MaxInt(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return b
|
||||
return y
|
||||
}
|
||||
|
||||
func clamp(x, a, b int) int {
|
||||
// Clamp restricts values to a minimum and maximum value
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// clamp(6, 3, 8) => 4
|
||||
// clamp(1, 3, 8) => 3
|
||||
// clamp(9, 3, 8) => 8
|
||||
//
|
||||
func Clamp(x, a, b int) int {
|
||||
if a > x {
|
||||
return a
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
. "github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_DoesNotInclude(t *testing.T) {
|
||||
@ -74,7 +74,8 @@ func Test_FindMatch(t *testing.T) {
|
||||
|
||||
expected := [][]string([][]string{[]string{"SSID: 7E5B5C", "7E5B5C"}})
|
||||
result = FindMatch(`s*SSID: (.+)s*`, "SSID: 7E5B5C")
|
||||
Equal(t, expected, result)
|
||||
|
||||
assert.Equal(t, expected, result)
|
||||
}
|
||||
|
||||
func Test_Includes(t *testing.T) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user