diff --git a/cmd/cheat/main.go b/cmd/cheat/main.go index 309a09e..1453a39 100755 --- a/cmd/cheat/main.go +++ b/cmd/cheat/main.go @@ -39,7 +39,7 @@ func main() { } // initialize the configs - conf, err := config.New(opts, confpath) + conf, err := config.New(opts, confpath, true) if err != nil { fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err) os.Exit(1) diff --git a/internal/config/config.go b/internal/config/config.go index 0f5a3d0..3101d41 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -22,7 +22,7 @@ type Config struct { } // New returns a new Config struct -func New(opts map[string]interface{}, confPath string) (Config, error) { +func New(opts map[string]interface{}, confPath string, resolve bool) (Config, error) { // read the config file buf, err := ioutil.ReadFile(confPath) @@ -49,13 +49,22 @@ func New(opts map[string]interface{}, confPath string) (Config, error) { } // follow symlinks - expanded, err = filepath.EvalSymlinks(expanded) - if err != nil { - return Config{}, fmt.Errorf( - "failed to resolve symlink: %s, %v", - expanded, - err, - ) + // + // NB: `resolve` is an ugly kludge that exists for the sake of unit-tests. + // It's necessary because `EvalSymlinks` will error if the symlink points + // to a non-existent location on the filesystem. When unit-testing, + // however, we don't want to have dependencies on the filesystem. As such, + // `resolve` is a switch that allows us to turn off symlink resolution when + // running the config tests. + if resolve { + expanded, err = filepath.EvalSymlinks(expanded) + if err != nil { + return Config{}, fmt.Errorf( + "failed to resolve symlink: %s, %v", + expanded, + err, + ) + } } conf.Cheatpaths[i].Path = expanded diff --git a/internal/config/config_test.go b/internal/config/config_test.go index fcf282c..c6a1dac 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -1,26 +1,23 @@ package config import ( - //"os" - //"path/filepath" - //"reflect" + "os" + "path/filepath" + "reflect" "testing" - //"github.com/davecgh/go-spew/spew" - //"github.com/mitchellh/go-homedir" + "github.com/davecgh/go-spew/spew" + "github.com/mitchellh/go-homedir" - //"github.com/cheat/cheat/internal/cheatpath" - //"github.com/cheat/cheat/internal/mock" + "github.com/cheat/cheat/internal/cheatpath" + "github.com/cheat/cheat/internal/mock" ) -// BUG: changes pertaining to symlink handling introduced in 3.0.4 break this -// test. -/* // TestConfig asserts that the configs are loaded correctly func TestConfigSuccessful(t *testing.T) { // initialize a config - conf, err := New(map[string]interface{}{}, mock.Path("conf/conf.yml")) + conf, err := New(map[string]interface{}{}, mock.Path("conf/conf.yml"), false) if err != nil { t.Errorf("failed to parse config file: %v", err) } @@ -66,14 +63,13 @@ func TestConfigSuccessful(t *testing.T) { ) } } -*/ // TestConfigFailure asserts that an error is returned if the config file // cannot be read. func TestConfigFailure(t *testing.T) { // attempt to read a non-existent config file - _, err := New(map[string]interface{}{}, "/does-not-exit") + _, err := New(map[string]interface{}{}, "/does-not-exit", false) if err == nil { t.Errorf("failed to error on unreadable config") } @@ -83,20 +79,19 @@ func TestConfigFailure(t *testing.T) { // specified in the configs func TestEmptyEditor(t *testing.T) { - /* // clear the environment variables os.Setenv("VISUAL", "") os.Setenv("EDITOR", "") // initialize a config - conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml")) + conf, err := New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false) if err == nil { t.Errorf("failed to return an error on empty editor") } // set editor, and assert that it is respected os.Setenv("EDITOR", "foo") - conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml")) + conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false) if err != nil { t.Errorf("failed to init configs: %v", err) } @@ -106,12 +101,11 @@ func TestEmptyEditor(t *testing.T) { // set visual, and assert that it overrides editor os.Setenv("VISUAL", "bar") - conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml")) + conf, err = New(map[string]interface{}{}, mock.Path("conf/empty.yml"), false) if err != nil { t.Errorf("failed to init configs: %v", err) } if conf.Editor != "bar" { t.Errorf("failed to respect editor: want: bar, got: %s", conf.Editor) } - */ }