1
0
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:
Chris Cummer 2019-10-30 17:35:00 -07:00 committed by GitHub
parent 837dc92cfc
commit 1bfca29d17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 857 additions and 69 deletions

View File

@ -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 # detect GOPATH if not set
ifndef $(GOPATH) ifndef $(GOPATH)
@ -30,6 +30,10 @@ build:
contrib_check: contrib_check:
npx all-contributors-cli check npx all-contributors-cli check
coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
install: install:
@echo "Installing wtfutil..." @echo "Installing wtfutil..."
@go clean @go clean

View File

@ -14,8 +14,8 @@ type Colors struct {
BorderNormal string BorderNormal string
Checked string Checked string
Foreground string Foreground string
HighlightFore string
HighlightBack string HighlightBack string
HighlightFore string
Text string Text string
Title string Title string
@ -83,11 +83,11 @@ func NewCommonSettingsFromModule(name, defaultTitle string, defaultFocusable boo
PositionSettings: NewPositionSettingsFromYAML(name, moduleConfig), PositionSettings: NewPositionSettingsFromYAML(name, moduleConfig),
Bordered: moduleConfig.UBool("border", true), Bordered: moduleConfig.UBool("border", true),
Config: moduleConfig,
Enabled: moduleConfig.UBool("enabled", false), Enabled: moduleConfig.UBool("enabled", false),
Focusable: moduleConfig.UBool("focusable", defaultFocusable), Focusable: moduleConfig.UBool("focusable", defaultFocusable),
RefreshInterval: moduleConfig.UInt("refreshInterval", 300), RefreshInterval: moduleConfig.UInt("refreshInterval", 300),
Title: moduleConfig.UString("title", defaultTitle), Title: moduleConfig.UString("title", defaultTitle),
Config: moduleConfig,
focusChar: moduleConfig.UInt("focusChar", -1), focusChar: moduleConfig.UInt("focusChar", -1),
} }
@ -135,7 +135,7 @@ func (common *Common) RightAlignFormat(width int) string {
return fmt.Sprintf("%%%ds", width-borderOffset) 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 := "" sigils := ""
if len > 1 { if len > 1 {

187
cfg/common_settings_test.go Normal file
View 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()))
}

View File

@ -0,0 +1,14 @@
package cfg
import (
"errors"
)
var (
errTest = errors.New("Busted")
)
func ExampleDisplayError() {
displayError(errTest)
// Output: Error: Busted
}

View File

@ -41,10 +41,10 @@ func NewPositionSettingsFromYAML(moduleName string, moduleConfig *config.Config)
pos := PositionSettings{ pos := PositionSettings{
Validations: validations, Validations: validations,
Top: validations.valueFor("top"), Top: validations.intValueFor("top"),
Left: validations.valueFor("left"), Left: validations.intValueFor("left"),
Width: validations.valueFor("width"), Width: validations.intValueFor("width"),
Height: validations.valueFor("height"), Height: validations.intValueFor("height"),
} }
return pos return pos

View File

@ -54,6 +54,8 @@ func (posVal *positionValidation) String() string {
return fmt.Sprintf("Invalid value for %s:\t%d", aurora.Yellow(posVal.name), posVal.intVal) 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 { func newPositionValidation(name string, intVal int, err error) *positionValidation {
posVal := &positionValidation{ posVal := &positionValidation{
err: err, err: err,

View 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")
}

View File

@ -18,7 +18,7 @@ func (vals *Validations) append(key string, posVal Validatable) {
vals.validations[key] = posVal vals.validations[key] = posVal
} }
func (vals *Validations) valueFor(key string) int { func (vals *Validations) intValueFor(key string) int {
val := vals.validations[key] val := vals.validations[key]
if val != nil { if val != nil {
return val.IntValue() return val.IntValue()

38
cfg/validations_test.go Normal file
View 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))
})
}
}

View File

@ -22,7 +22,8 @@ func NewChecklist(checkedIcon, uncheckedIcon string) Checklist {
/* -------------------- Exported Functions -------------------- */ /* -------------------- 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) { func (list *Checklist) Add(checked bool, text string) {
item := NewChecklistItem( item := NewChecklistItem(
checked, checked,
@ -49,7 +50,9 @@ func (list *Checklist) CheckedItems() []*ChecklistItem {
// Delete removes the selected item from the checklist // Delete removes the selected item from the checklist
func (list *Checklist) Delete(selectedIndex int) { func (list *Checklist) Delete(selectedIndex int) {
list.Items = append(list.Items[:selectedIndex], list.Items[selectedIndex+1:]...) 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 // IsSelectable returns true if the checklist has selectable items, false if it does not
@ -75,7 +78,7 @@ func (list *Checklist) LongestLine() int {
return maxLen return maxLen
} }
// IndexByItem returns the index of a giving item if found ,otherwise returns 0 with ok set to false // IndexByItem returns the index of a giving item if found, otherwise returns 0 with ok set to false
func (list *Checklist) IndexByItem(selectableItem *ChecklistItem) (index int, ok bool) { func (list *Checklist) IndexByItem(selectableItem *ChecklistItem) (index int, ok bool) {
for idx, item := range list.Items { for idx, item := range list.Items {
if item == selectableItem { if item == selectableItem {

View File

@ -10,8 +10,8 @@ func testChecklistItem() *ChecklistItem {
item := NewChecklistItem( item := NewChecklistItem(
false, false,
"test", "test",
"x", "",
" ", "",
) )
return item return item
} }

436
checklist/checklist_test.go Normal file
View 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")
})
}
}

View File

@ -8,7 +8,6 @@ import (
goFlags "github.com/jessevdk/go-flags" goFlags "github.com/jessevdk/go-flags"
"github.com/olebedev/config" "github.com/olebedev/config"
"github.com/wtfutil/wtf/help" "github.com/wtfutil/wtf/help"
"github.com/wtfutil/wtf/utils"
) )
// Flags is the container for command line flag data // 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 // 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 { if err != nil {
fmt.Printf("Error: %v\n", err) fmt.Printf("Error: %v\n", err)
os.Exit(1) os.Exit(1)

1
go.mod
View File

@ -10,6 +10,7 @@ require (
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/VictorAvelar/devto-api-go v1.0.0 github.com/VictorAvelar/devto-api-go v1.0.0
github.com/adlio/trello v1.4.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/alecthomas/chroma v0.6.8
github.com/andygrunwald/go-gerrit v0.0.0-20190825170856-5959a9bf9ff8 github.com/andygrunwald/go-gerrit v0.0.0-20190825170856-5959a9bf9ff8
github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d

View File

@ -4,8 +4,6 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"github.com/wtfutil/wtf/utils"
) )
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
@ -30,7 +28,7 @@ func LogFileMissing() bool {
} }
func LogFilePath() string { func LogFilePath() string {
dir, err := utils.Home() dir, err := os.UserHomeDir()
if err != nil { if err != nil {
return "" return ""
} }

View File

@ -2,8 +2,9 @@ package buildkite
import ( import (
"fmt" "fmt"
"github.com/wtfutil/wtf/utils"
"net/http" "net/http"
"github.com/wtfutil/wtf/utils"
) )
type Pipeline struct { type Pipeline struct {
@ -61,7 +62,7 @@ func (widget *Widget) recentBuilds(pipeline PipelineSettings) ([]Build, error) {
} }
builds := []Build{} builds := []Build{}
err = utils.ParseJson(&builds, resp.Body) err = utils.ParseJSON(&builds, resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -28,7 +28,7 @@ func (client *Client) BuildsFor() ([]*Build, error) {
return builds, err return builds, err
} }
err = utils.ParseJson(&builds, resp.Body) err = utils.ParseJSON(&builds, resp.Body)
if err != nil { if err != nil {
return builds, err return builds, err
} }

View File

@ -16,7 +16,7 @@ func GetMessages(roomId string, numberOfMessages int, apiToken string) ([]Messag
return nil, err return nil, err
} }
err = utils.ParseJson(&messages, resp.Body) err = utils.ParseJSON(&messages, resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -32,7 +32,7 @@ func GetRoom(roomUri, apiToken string) (*Room, error) {
return nil, err return nil, err
} }
err = utils.ParseJson(&rooms, resp.Body) err = utils.ParseJSON(&rooms, resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -19,7 +19,7 @@ func GetStories(storyType string) ([]int, error) {
return storyIds, err return storyIds, err
} }
err = utils.ParseJson(&storyIds, resp.Body) err = utils.ParseJSON(&storyIds, resp.Body)
if err != nil { if err != nil {
return storyIds, err return storyIds, err
} }
@ -36,7 +36,7 @@ func GetStory(id int) (Story, error) {
return story, err return story, err
} }
err = utils.ParseJson(&story, resp.Body) err = utils.ParseJSON(&story, resp.Body)
if err != nil { if err != nil {
return story, err return story, err
} }

View File

@ -40,7 +40,7 @@ func (widget *Widget) Create(jenkinsURL string, username string, apiKey string)
return view, err return view, err
} }
err = utils.ParseJson(view, resp.Body) err = utils.ParseJSON(view, resp.Body)
if err != nil { if err != nil {
return view, err return view, err
} }

View File

@ -38,7 +38,7 @@ func (widget *Widget) IssuesFor(username string, projects []string, jql string)
} }
searchResult := &SearchResult{} searchResult := &SearchResult{}
err = utils.ParseJson(searchResult, resp.Body) err = utils.ParseJSON(searchResult, resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -11,6 +11,7 @@ func Test_generateTitle(t *testing.T) {
title string title string
namespaces []string namespaces []string
} }
testCases := []struct { testCases := []struct {
name string name string
fields fields fields fields
@ -46,6 +47,7 @@ func Test_generateTitle(t *testing.T) {
want: "Test Explicit Title", want: "Test Explicit Title",
}, },
} }
for _, tt := range testCases { for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
widget := &Widget{ widget := &Widget{

View File

@ -18,7 +18,7 @@ func CurrentActiveItems(accessToken, assignedToName string, activeOnly bool) (*A
return items, err return items, err
} }
err = utils.ParseJson(&items, resp.Body) err = utils.ParseJSON(&items, resp.Body)
return items, nil return items, nil
} }

View File

@ -33,7 +33,7 @@ func GetLinks(subreddit string, sortMode string, topTimePeriod string) ([]Link,
return nil, fmt.Errorf(resp.Status) return nil, fmt.Errorf(resp.Status)
} }
var m RedditDocument var m RedditDocument
err = utils.ParseJson(&m, resp.Body) err = utils.ParseJSON(&m, resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -26,7 +26,7 @@ func BuildsFor(settings *Settings) (*Builds, error) {
return builds, err return builds, err
} }
err = utils.ParseJson(&builds, resp.Body) err = utils.ParseJSON(&builds, resp.Body)
if err != nil { if err != nil {
return builds, err return builds, err
} }

View File

@ -3,7 +3,7 @@ package utils
import ( import (
"testing" "testing"
. "github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_MapToStrs(t *testing.T) { func Test_MapToStrs(t *testing.T) {
@ -18,7 +18,7 @@ func Test_MapToStrs(t *testing.T) {
source[val] = val source[val] = val
} }
Equal(t, expected, MapToStrs(source)) assert.Equal(t, expected, MapToStrs(source))
} }
func Test_ToInts(t *testing.T) { func Test_ToInts(t *testing.T) {
@ -29,16 +29,23 @@ func Test_ToInts(t *testing.T) {
source[idx] = val source[idx] = val
} }
Equal(t, expected, ToInts(source)) assert.Equal(t, expected, ToInts(source))
} }
func Test_ToStrs(t *testing.T) { 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)) fromInts := make([]interface{}, 3)
for idx, val := range expected { for idx, val := range expectedInts {
source[idx] = val 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))
} }

View File

@ -26,16 +26,10 @@ func ExpandHomeDir(path string) (string, error) {
return "", errors.New("cannot expand user-specific home dir") return "", errors.New("cannot expand user-specific home dir")
} }
dir, err := Home() dir, err := os.UserHomeDir()
if err != nil { if err != nil {
return "", err return "", err
} }
return filepath.Join(dir, path[1:]), nil 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
View 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)
})
}
}

View File

@ -3,18 +3,26 @@ package utils
import ( import (
"testing" "testing"
. "github.com/stretchr/testify/assert" "github.com/rivo/tview"
"github.com/stretchr/testify/assert"
) )
func Test_CenterText(t *testing.T) { func Test_CenterText(t *testing.T) {
Equal(t, "cat", CenterText("cat", -9)) assert.Equal(t, "cat", CenterText("cat", -9))
Equal(t, "cat", CenterText("cat", 0)) assert.Equal(t, "cat", CenterText("cat", 0))
Equal(t, " cat ", CenterText("cat", 9)) 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) { func Test_RowPadding(t *testing.T) {
Equal(t, "", RowPadding(0, 0)) assert.Equal(t, "", RowPadding(0, 0))
Equal(t, "", RowPadding(5, 2)) assert.Equal(t, "", RowPadding(5, 2))
Equal(t, " ", RowPadding(1, 2)) assert.Equal(t, " ", RowPadding(1, 2))
Equal(t, " ", RowPadding(0, 5)) assert.Equal(t, " ", RowPadding(0, 5))
} }

View File

@ -121,8 +121,8 @@ func ReadFileBytes(filePath string) ([]byte, error) {
return fileData, nil return fileData, nil
} }
// ParseJson is a standard JSON reader from text // ParseJSON is a standard JSON reader from text
func ParseJson(obj interface{}, text io.Reader) error { func ParseJSON(obj interface{}, text io.Reader) error {
d := json.NewDecoder(text) d := json.NewDecoder(text)
return d.Decode(obj) return d.Decode(obj)
} }
@ -139,10 +139,10 @@ func CalculateDimensions(moduleConfig, globalConfig *config.Config) (int, int) {
rows := ToInts(globalConfig.UList("wtf.grid.rows")) rows := ToInts(globalConfig.UList("wtf.grid.rows"))
// Make sure the values are in bounds // Make sure the values are in bounds
left = clamp(left, 0, len(cols)-1) left = Clamp(left, 0, len(cols)-1)
top = clamp(top, 0, len(rows)-1) top = Clamp(top, 0, len(rows)-1)
width = clamp(width, 0, len(cols)-left) width = Clamp(width, 0, len(cols)-left)
height = clamp(height, 0, len(rows)-top) height = Clamp(height, 0, len(rows)-top)
// Start with the border subtracted and add all the spanned rows and cols // Start with the border subtracted and add all the spanned rows and cols
w, h := -2, -2 w, h := -2, -2
@ -154,20 +154,35 @@ func CalculateDimensions(moduleConfig, globalConfig *config.Config) (int, int) {
} }
// The usable space may be empty // The usable space may be empty
w = max(w, 0) w = MaxInt(w, 0)
h = max(h, 0) h = MaxInt(h, 0)
return w, h return w, h
} }
func max(a, b int) int { // MaxInt returns the larger of x or y
if a > b { //
return a // 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 { if a > x {
return a return a
} }

View File

@ -5,7 +5,7 @@ import (
"reflect" "reflect"
"testing" "testing"
. "github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_DoesNotInclude(t *testing.T) { func Test_DoesNotInclude(t *testing.T) {
@ -74,7 +74,8 @@ func Test_FindMatch(t *testing.T) {
expected := [][]string([][]string{[]string{"SSID: 7E5B5C", "7E5B5C"}}) expected := [][]string([][]string{[]string{"SSID: 7E5B5C", "7E5B5C"}})
result = FindMatch(`s*SSID: (.+)s*`, "SSID: 7E5B5C") result = FindMatch(`s*SSID: (.+)s*`, "SSID: 7E5B5C")
Equal(t, expected, result)
assert.Equal(t, expected, result)
} }
func Test_Includes(t *testing.T) { func Test_Includes(t *testing.T) {