Skip to content

Commit

Permalink
Add test for Run in main.go
Browse files Browse the repository at this point in the history
  • Loading branch information
hk21702 committed Jan 8, 2025
1 parent a900557 commit 2c43b75
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 49 deletions.
4 changes: 2 additions & 2 deletions cmd/insights/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ type rootConfig struct {

var defaultRootConfig = rootConfig{
Verbose: false,
ConsentDir: constants.DefaultConfigPath,
InsightsDir: constants.DefaultCachePath,
ConsentDir: constants.GetDefaultConfigPath(),
InsightsDir: constants.GetDefaultCachePath(),
}

// Registers commands and returns a new app
Expand Down
72 changes: 72 additions & 0 deletions cmd/insights/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package main

import (
"errors"
"testing"
"time"
)

type testApp struct {
done chan struct{}
runError bool
userErrorReturn bool
}

func (a *testApp) Run() error {
<-a.done
if a.runError {
return errors.New(("run error!"))
}
return nil
}

func (a testApp) UsageError() bool {
return a.userErrorReturn
}

func (a testApp) Quit() {
close(a.done)
}

func TestRun(t *testing.T) {
t.Parallel()

tests := map[string]struct {
runError bool
usageError bool

wantReturnCode int
}{
"Run and exit successfully": {},
"Run and exit error": {runError: true, wantReturnCode: 1},
"Run and exit with usage error": {usageError: true, runError: true, wantReturnCode: 2},
"Run and return with usage error but no run error": {usageError: true, wantReturnCode: 0},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
a := testApp{
done: make(chan struct{}),
runError: tc.runError,
userErrorReturn: tc.usageError,
}

var rc int
wait := make(chan struct{})

go func() {
rc = run(&a)
close(wait)
}()

time.Sleep(100 * time.Millisecond)

a.Quit()
<-wait

if rc != tc.wantReturnCode {
t.Errorf("run() = %v, want %v", rc, tc.wantReturnCode)
}
})
}
}
37 changes: 24 additions & 13 deletions internal/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,35 @@ const (
DefaultLogLevel = slog.LevelInfo
)

var (
// DefaultConfigPath is the default path to the configuration file
DefaultConfigPath = userConfigDir(os.UserCacheDir) + string(os.PathSeparator) + DefaultAppFolder
type options struct {
baseDir func() (string, error)
}

// DefaultCachePath is the default path to the cache directory
DefaultCachePath = userCacheDir(os.UserConfigDir) + string(os.PathSeparator) + DefaultAppFolder
)
type option func(*options)

func userConfigDir(osUserConfigDir func() (string, error)) string {
dir, err := osUserConfigDir()
if err != nil {
return ""
// GetDefaultConfigPath is the default path to the configuration file
func GetDefaultConfigPath(opts ...option) string {
o := options{baseDir: os.UserCacheDir}
for _, opt := range opts {
opt(&o)
}
return dir

return getBaseDir(o.baseDir) + string(os.PathSeparator) + DefaultAppFolder
}

// GetDefaultCachePath is the default path to the cache directory
func GetDefaultCachePath(opts ...option) string {
o := options{baseDir: os.UserConfigDir}
for _, opt := range opts {
opt(&o)
}

return getBaseDir(o.baseDir) + string(os.PathSeparator) + DefaultAppFolder
}

func userCacheDir(osUserCacheDir func() (string, error)) string {
dir, err := osUserCacheDir()
// getBaseDir is a helper function to handle the case where the baseDir function returns an error, and instead return an empty string
func getBaseDir(baseDirFunc func() (string, error)) string {
dir, err := baseDirFunc()
if err != nil {
return ""
}
Expand Down
68 changes: 34 additions & 34 deletions internal/constants/constants_test.go
Original file line number Diff line number Diff line change
@@ -1,82 +1,82 @@
package constants
package constants_test

import (
"fmt"
"os"
"testing"

"github.com/stretchr/testify/require"
"github.com/ubuntu/ubuntu-insights/internal/constants"
)

func Test_userConfigDir(t *testing.T) {
func Test_GetUserConfigDir(t *testing.T) {
t.Parallel()
tests := []struct {
name string

tests := map[string]struct {
want string
mock func() (string, error)
}{
{
name: "os.UserConfigDir success",
want: "abc/def",
"os.UserConfigDir success": {
want: "abc/def" + string(os.PathSeparator) + constants.DefaultAppFolder,
mock: func() (string, error) {
return "abc/def", nil
},
},
{
name: "os.UserConfigDir error",
want: "",
"os.UserConfigDir error": {
want: string(os.PathSeparator) + constants.DefaultAppFolder,
mock: func() (string, error) {
return "", fmt.Errorf("error")
},
},
{
name: "os.UserConfigDir error 2",
want: "",
"os.UserConfigDir error 2": {
want: string(os.PathSeparator) + constants.DefaultAppFolder,
mock: func() (string, error) {
return "abc", fmt.Errorf("error")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := userConfigDir(tt.mock); got != tt.want {
t.Errorf("userConfigDir() = %v, want %v", got, tt.want)
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
t.Parallel()

opts := []constants.Option{constants.WithBaseDir(tt.mock)}
require.Equal(t, tt.want, constants.GetDefaultConfigPath(opts...))
})
}
}

func Test_userCacheDir(t *testing.T) {
t.Parallel()
tests := []struct {
name string

tests := map[string]struct {
want string
mock func() (string, error)
}{
{
name: "os.UserCacheDir success",
want: "def/abc",
"os.UserCacheDir success": {
want: "def/abc" + string(os.PathSeparator) + constants.DefaultAppFolder,
mock: func() (string, error) {
return "def/abc", nil
},
},
{
name: "os.UserCacheDir error",
want: "",
"os.UserCacheDir error": {
want: string(os.PathSeparator) + constants.DefaultAppFolder,
mock: func() (string, error) {
return "", fmt.Errorf("error")
},
},
{
name: "os.UserCacheDir error 2",
want: "",
"os.UserCacheDir error 2": {
want: string(os.PathSeparator) + constants.DefaultAppFolder,
mock: func() (string, error) {
return "abc", fmt.Errorf("error")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := userCacheDir(tt.mock); got != tt.want {
t.Errorf("userCacheDir() = %v, want %v", got, tt.want)
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
t.Parallel()

opts := []constants.Option{constants.WithBaseDir(tt.mock)}
require.Equal(t, tt.want, constants.GetDefaultCachePath(opts...))
})
}
}
9 changes: 9 additions & 0 deletions internal/constants/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package constants

type Option = option

func WithBaseDir(baseDir func() (string, error)) option {
return func(o *options) {
o.baseDir = baseDir
}
}

0 comments on commit 2c43b75

Please sign in to comment.