Permalink
Browse files

Promote config.Config to an interface

Sooo, we can mock it during command testing. When testing is hard, mock
it so you look good in front of others and don't care about all the
shit and potential bugs it can slip through. But hey, tests!
  • Loading branch information...
1 parent fca01f5 commit a71a832c8b75f0705b6e10a1b08e4f387186393e @gsamokovarov committed Mar 13, 2017
Showing with 36 additions and 23 deletions.
  1. +1 −1 cli/command.go
  2. +3 −3 cli/command_test.go
  3. +1 −1 cmd/cd.go
  4. +1 −1 cmd/chdir.go
  5. +1 −1 cmd/clean.go
  6. +1 −1 cmd/help.go
  7. +1 −1 cmd/hint.go
  8. +1 −1 cmd/pin.go
  9. +1 −1 cmd/shell.go
  10. +1 −1 cmd/top.go
  11. +1 −1 cmd/version.go
  12. +17 −4 config/config.go
  13. +2 −2 config/entries.go
  14. +2 −2 config/pin.go
  15. +2 −2 config/search.go
View
@@ -8,7 +8,7 @@ import (
)
// CommandFn represents a command handler function.
-type CommandFn func(Args, *config.Config)
+type CommandFn func(Args, config.Config)
// Command represents a command line action.
type Command struct {
View
@@ -7,22 +7,22 @@ import (
)
func TestDispatchCommand(t *testing.T) {
- RegisterCommand("test", "A testing command.", func(Args, *config.Config) {})
+ RegisterCommand("test", "A testing command.", func(Args, config.Config) {})
args := Args([]string{"test"})
if _, err := DispatchCommand(args, "default"); err == nil {
t.Errorf("Expected an error on missing registered default command")
}
- RegisterCommand("default", "A testing command.", func(Args, *config.Config) {})
+ RegisterCommand("default", "A testing command.", func(Args, config.Config) {})
if command, _ := DispatchCommand(args, "default"); command.Name != "test" {
t.Errorf("Expected test command to be dispatched and executed")
}
}
func TestCommandIsOption(t *testing.T) {
- command := &Command{"--test", "Testing command.", func(Args, *config.Config) {}}
+ command := &Command{"--test", "Testing command.", func(Args, config.Config) {}}
if !command.IsOption() {
t.Errorf("Expected --test command to be an option")
View
@@ -13,7 +13,7 @@ import (
const proximity = 5
const osSeparator = string(os.PathSeparator)
-func cdCmd(args cli.Args, conf *config.Config) {
+func cdCmd(args cli.Args, conf config.Config) {
term := args.CommandName()
entries, err := conf.ReadEntries()
View
@@ -9,7 +9,7 @@ import (
"github.com/gsamokovarov/jump/scoring"
)
-func updateCmd(args cli.Args, conf *config.Config) {
+func updateCmd(args cli.Args, conf config.Config) {
dir, err := os.Getwd()
if len(args) == 0 && err != nil {
cli.Exitf(1, "err: %s\n", err)
View
@@ -8,7 +8,7 @@ import (
"github.com/gsamokovarov/jump/scoring"
)
-func cleanCmd(args cli.Args, conf *config.Config) {
+func cleanCmd(args cli.Args, conf config.Config) {
entries, err := conf.ReadEntries()
if err != nil {
cli.Exitf(1, "%s\n", err)
View
@@ -19,7 +19,7 @@ Options:{{range .Options}}
{{printf "%-12s %s" .Name .Desc}}{{end}}
`
-func helpCmd(cli.Args, *config.Config) {
+func helpCmd(cli.Args, config.Config) {
tmpl := template.Must(template.New("--help").Parse(helpUsage))
tmpl.Execute(os.Stderr, cli.Registry)
}
View
@@ -8,7 +8,7 @@ import (
"github.com/gsamokovarov/jump/scoring"
)
-func hintCmd(args cli.Args, conf *config.Config) {
+func hintCmd(args cli.Args, conf config.Config) {
var hints scoring.Entries
term := args.CommandName()
View
@@ -13,7 +13,7 @@ var pinUsageMsg = `jump pin term [directory]
No term specified. See the signature of the pin call above.
`
-func pinCmd(args cli.Args, conf *config.Config) {
+func pinCmd(args cli.Args, conf config.Config) {
var err error
term := args.CommandName()
View
@@ -8,7 +8,7 @@ import (
"github.com/gsamokovarov/jump/shell"
)
-func shellCmd(args cli.Args, _ *config.Config) {
+func shellCmd(args cli.Args, _ config.Config) {
hint := args.CommandName()
if len(hint) == 0 {
hint = os.Getenv("SHELL")
View
@@ -7,7 +7,7 @@ import (
"github.com/gsamokovarov/jump/config"
)
-func topCmd(args cli.Args, conf *config.Config) {
+func topCmd(args cli.Args, conf config.Config) {
entries, err := conf.ReadEntries()
if err != nil {
cli.Exitf(1, "%s\n", err)
View
@@ -7,7 +7,7 @@ import (
const version = "0.11.0"
-func versionCmd(cli.Args, *config.Config) {
+func versionCmd(cli.Args, config.Config) {
cli.Outf("%s\n", version)
}
View
@@ -4,6 +4,8 @@ import (
"os"
"os/user"
"path/filepath"
+
+ "github.com/gsamokovarov/jump/scoring"
)
const (
@@ -15,7 +17,18 @@ const (
// Config represents the config directory and all the miscellaneous
// configuration files we can have in there.
-type Config struct {
+type Config interface {
+ ReadEntries() (*scoring.Entries, error)
+ WriteEntries(*scoring.Entries) error
+
+ ReadSearch() Search
+ WriteSearch(string, int) error
+
+ FindPin(string) (string, bool)
+ WritePin(string, string) error
+}
+
+type fileConfig struct {
Dir string
Scores string
Search string
@@ -26,7 +39,7 @@ type Config struct {
//
// If the directories don't already exists, they are created and if the score
// file is present, it is loaded.
-func Setup(dir string) (*Config, error) {
+func Setup(dir string) (Config, error) {
// We get the directory check for free form os.MkdirAll.
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, err
@@ -36,13 +49,13 @@ func Setup(dir string) (*Config, error) {
search := filepath.Join(dir, defaultSearchFile)
pins := filepath.Join(dir, defaultPinsFile)
- return &Config{dir, scores, search, pins}, nil
+ return &fileConfig{dir, scores, search, pins}, nil
}
// SetupDefault setups the config folder from a directory path.
//
// If the directory path is an empty string, the path is automatically guessed.
-func SetupDefault(dir string) (*Config, error) {
+func SetupDefault(dir string) (Config, error) {
dir, err := normalizeDir(dir)
if err != nil {
return nil, err
View
@@ -8,7 +8,7 @@ import (
// ReadEntries returns the current entries for the config.
//
// If the scores file is empty, the returned entries are empty.
-func (c *Config) ReadEntries() (*scoring.Entries, error) {
+func (c *fileConfig) ReadEntries() (*scoring.Entries, error) {
var entries scoring.Entries
scoresFile, err := createOrOpenLockedFile(c.Scores)
@@ -28,7 +28,7 @@ func (c *Config) ReadEntries() (*scoring.Entries, error) {
// WriteEntries the input scoring entries to a file.
//
// Sorts the entries before writing them to disk.
-func (c *Config) WriteEntries(entries *scoring.Entries) error {
+func (c *fileConfig) WriteEntries(entries *scoring.Entries) error {
scoresFile, err := createOrOpenLockedFile(c.Scores)
if err != nil {
return err
View
@@ -7,7 +7,7 @@ import (
// FindPin tries to the directory from a pinned search term.
//
// If no search pinned search term is found.
-func (c *Config) FindPin(term string) (dir string, found bool) {
+func (c *fileConfig) FindPin(term string) (dir string, found bool) {
pinsFile, err := createOrOpenLockedFile(c.Pins)
if err != nil {
return
@@ -24,7 +24,7 @@ func (c *Config) FindPin(term string) (dir string, found bool) {
}
// WritePin saves a pinned search term into a file.
-func (c *Config) WritePin(pin, value string) error {
+func (c *fileConfig) WritePin(pin, value string) error {
pinsFile, err := createOrOpenLockedFile(c.Pins)
if err != nil {
return err
View
@@ -14,7 +14,7 @@ type Search struct {
// ReadSearch reads the last saved search entry.
//
// If the last search doesn't exist, a zero value Search is returned.
-func (c *Config) ReadSearch() (search Search) {
+func (c *fileConfig) ReadSearch() (search Search) {
searchFile, err := createOrOpenLockedFile(c.Search)
if err != nil {
return
@@ -28,7 +28,7 @@ func (c *Config) ReadSearch() (search Search) {
}
// WriteSearch writes the last search entry to the current search entry.
-func (c *Config) WriteSearch(term string, index int) error {
+func (c *fileConfig) WriteSearch(term string, index int) error {
searchFile, err := createOrOpenLockedFile(c.Search)
if err != nil {
return err

0 comments on commit a71a832

Please sign in to comment.