Skip to content

Commit

Permalink
BUGIFX-60: Increase unit test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
grafviktor committed Apr 4, 2024
1 parent 22657e8 commit 6bb9a8a
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 24 deletions.
4 changes: 2 additions & 2 deletions internal/logger/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"testing"
)

func Test_LoggerConstructor(t *testing.T) {
func TestLoggerConstructor(t *testing.T) {
// Create a temporary directory for testing
tmpDir, err := os.MkdirTemp("", "testlog")
if err != nil {
Expand Down Expand Up @@ -66,7 +66,7 @@ func Test_LoggerConstructor(t *testing.T) {
}
}

func Test_LoggerMethods(t *testing.T) {
func TestLoggerMethods(t *testing.T) {
// Create a temporary directory for testing
tmpDir, err := os.MkdirTemp("", "testlog")
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/model/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
)

func Test_NewHost(t *testing.T) {
func TestNewHost(t *testing.T) {
// Create a new host using the NewHost function
expectedHost := Host{
ID: 1,
Expand All @@ -28,7 +28,7 @@ func Test_NewHost(t *testing.T) {
}
}

func Test_CloneHost(t *testing.T) {
func TestCloneHost(t *testing.T) {
// Create a host to clone
originalHost := Host{
ID: 1,
Expand Down
6 changes: 3 additions & 3 deletions internal/ui/component/hostedit/hostedit.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var (
debounceTime = time.Second * 1
)

type logger interface {
type iLogger interface {
Debug(format string, args ...any)
Info(format string, args ...any)
}
Expand Down Expand Up @@ -103,15 +103,15 @@ type editModel struct {
inputs []labeledInput
isNewHost bool
keyMap keyMap
logger logger
logger iLogger
ready bool
title string
viewport viewport.Model
debounceTag int
}

// New - returns new edit host form.
func New(ctx context.Context, storage storage.HostStorage, state *state.ApplicationState, log logger) *editModel {
func New(ctx context.Context, storage storage.HostStorage, state *state.ApplicationState, log iLogger) *editModel {
initialFocusedInput := inputTitle

// If we can't cast host id to int, that means we're adding a new host. Ignore the error
Expand Down
6 changes: 3 additions & 3 deletions internal/ui/component/hostlist/hostlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var (
defaultListTitle = "press 'n' to add a new host"
)

type logger interface {
type iLogger interface {
Debug(format string, args ...any)
Info(format string, args ...any)
Error(format string, args ...any)
Expand All @@ -50,7 +50,7 @@ type listModel struct {
repo storage.HostStorage
keyMap *keyMap
appState *state.ApplicationState
logger logger
logger iLogger
mode string
}

Expand All @@ -60,7 +60,7 @@ type listModel struct {
// appState - is the application state, usually we want to restore previous state when application restarts,
// for instance focus previously selected host.
// log - application logger.
func New(_ context.Context, storage storage.HostStorage, appState *state.ApplicationState, log logger) *listModel {
func New(_ context.Context, storage storage.HostStorage, appState *state.ApplicationState, log iLogger) *listModel {
delegate := list.NewDefaultDelegate()
delegateKeys := newDelegateKeyMap()

Expand Down
3 changes: 1 addition & 2 deletions internal/ui/component/hostlist/hostlist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func Test_listModel_Change_Selection(t *testing.T) {
{
"Select next using 'j' key",
2,

tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'j'}},
},
{
Expand Down Expand Up @@ -288,7 +287,7 @@ func Test_exitRemoveItemMode(t *testing.T) {

// Reject the action by pressing 'n' (it can be any key apart from 'y')
_, cmd := model.Update(tea.KeyMsg{
Type: -1,
Type: -1, // Type '-1' should be equal to 'KeyRunes'
Runes: []rune{'n'},
})

Expand Down
6 changes: 3 additions & 3 deletions internal/ui/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"github.com/grafviktor/goto/internal/utils/ssh"
)

type logger interface {
type iLogger interface {
Debug(format string, args ...any)
Info(format string, args ...any)
Error(format string, args ...any)
Expand All @@ -32,7 +32,7 @@ func New(
ctx context.Context,
storage storage.HostStorage,
appState *state.ApplicationState,
log logger,
log iLogger,
) mainModel {
m := mainModel{
modelHostList: hostlist.New(ctx, storage, appState, log),
Expand All @@ -51,7 +51,7 @@ type mainModel struct {
modelHostList tea.Model
modelHostEdit tea.Model
appState *state.ApplicationState
logger logger
logger iLogger
viewport viewport.Model
ready bool
}
Expand Down
68 changes: 68 additions & 0 deletions internal/ui/model_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package ui

import (
"context"
"testing"

tea "github.com/charmbracelet/bubbletea"
"github.com/grafviktor/goto/internal/mock"
"github.com/grafviktor/goto/internal/state"
"github.com/grafviktor/goto/internal/ui/message"
"github.com/grafviktor/goto/internal/utils/ssh"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNew(t *testing.T) {
model := New(context.TODO(), mock.NewMockStorage(true), MockAppState(), &mock.MockLogger{})
require.NotNil(t, model)
}

func TestUpdate_KeyMsg(t *testing.T) {
// Random key test - make sure that the app reacts on Ctrl+C
model := New(context.TODO(), mock.NewMockStorage(true), MockAppState(), &mock.MockLogger{})
_, cmd := model.Update(tea.KeyMsg{
Type: tea.KeyCtrlC,
})

assert.NotNil(t, model)
require.IsType(t, tea.QuitMsg{}, cmd(), "Wrong message type")
}

func TestUpdate_TerminalSizePolling(t *testing.T) {
// Ensure that when the model receives TerminalSizePolling it autogenerates 'WindowSizeMsg'
model := New(context.TODO(), mock.NewMockStorage(true), MockAppState(), &mock.MockLogger{})
assert.Equal(t, 0, model.appState.Width)
assert.Equal(t, 0, model.appState.Height)

_, cmds := model.Update(message.TerminalSizePolling{
Width: 10,
Height: 10,
})

var dst []tea.Msg
cmdToMessage(cmds, &dst)

require.Contains(t, dst, tea.WindowSizeMsg{
Width: 10,
Height: 10,
})
}

func MockAppState() *state.ApplicationState {
return &state.ApplicationState{
HostSSHConfig: &ssh.Config{},
}
}

func cmdToMessage(cmd tea.Cmd, messages *[]tea.Msg) {
result := cmd()

if batchMsg, ok := result.(tea.BatchMsg); ok {
for _, msg := range batchMsg {
cmdToMessage(msg, messages)
}
} else {
*messages = append(*messages, result)
}
}
12 changes: 4 additions & 8 deletions internal/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ import (
"github.com/grafviktor/goto/internal/storage"
)

type interfaceLogger interface {
Debug(format string, args ...any)
Info(format string, args ...any)
Error(format string, args ...any)
}

// Start - starts UI subsystem of the application.
func Start(ctx context.Context, storage storage.HostStorage, appState *state.ApplicationState, logger interfaceLogger) {
// Start - starts UI subsystem of the application. *state.ApplicationState should be substituted
// with interface type which would have getters and setters for appropriate fields, without doing it
// it's hard to use mock objects in unit tests of the child components. Search for 'MockAppState'.
func Start(ctx context.Context, storage storage.HostStorage, appState *state.ApplicationState, logger iLogger) {

Check warning on line 16 in internal/ui/ui.go

View check run for this annotation

Codecov / codecov/patch

internal/ui/ui.go#L16

Added line #L16 was not covered by tests
uiComponent := New(ctx, storage, appState, logger)
p := tea.NewProgram(&uiComponent, tea.WithAltScreen())

Expand Down
2 changes: 1 addition & 1 deletion internal/utils/ssh/cmd_win_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package ssh

import "testing"

func Test_BaseCMD(t *testing.T) {
func TestBaseCMD(t *testing.T) {
expected := "cmd /c ssh"
result := BaseCMD()

Expand Down

0 comments on commit 6bb9a8a

Please sign in to comment.