Add more coverage for loader and strengthen type safety.

This commit is contained in:
jregan
2019-01-24 19:55:44 -08:00
committed by Jeffrey Regan
parent 4d77c9f940
commit dcb5682594
10 changed files with 243 additions and 103 deletions

58
pkg/fs/confirmeddir.go Normal file
View File

@@ -0,0 +1,58 @@
package fs
import (
"path/filepath"
"strings"
)
// ConfirmedDir is a clean, absolute, delinkified path
// that was confirmed to point to an existing directory.
type ConfirmedDir string
// HasPrefix returns true if the directory argument
// is a prefix of self (d) from the point of view of
// a file system.
//
// I.e., it's true if the argument equals or contains
// self (d) in a file path sense.
//
// HasPrefix emulates the semantics of strings.HasPrefix
// such that the following are true:
//
// strings.HasPrefix("foobar", "foobar")
// strings.HasPrefix("foobar", "foo")
// strings.HasPrefix("foobar", "")
//
// d := fSys.ConfirmDir("/foo/bar")
// d.HasPrefix("/foo/bar")
// d.HasPrefix("/foo")
// d.HasPrefix("/")
//
// Not contacting a file system here to check for
// actual path existence.
//
// This is tested on linux, but will have trouble
// on other operating systems. As soon as related
// work is completed in the core filepath package,
// this code should be refactored to use it.
// See:
// https://github.com/golang/go/issues/18355
// https://github.com/golang/dep/issues/296
// https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33
// https://codereview.appspot.com/5712045
func (d ConfirmedDir) HasPrefix(path ConfirmedDir) bool {
if path.String() == string(filepath.Separator) || path == d {
return true
}
return strings.HasPrefix(
string(d),
string(path)+string(filepath.Separator))
}
func (d ConfirmedDir) Join(path string) string {
return filepath.Join(string(d), path)
}
func (d ConfirmedDir) String() string {
return string(d)
}

View File

@@ -0,0 +1,87 @@
package fs
import (
"testing"
)
func TestJoin(t *testing.T) {
fSys := MakeFakeFS()
err := fSys.Mkdir("/foo")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
d, f, err := fSys.CleanedAbs("/foo")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if f != "" {
t.Fatalf("unexpected file: %v", f)
}
if d.Join("bar") != "/foo/bar" {
t.Fatalf("expected join %s", d.Join("bar"))
}
}
func TestHasPrefix_Slash(t *testing.T) {
d, f, err := MakeFakeFS().CleanedAbs("/")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if f != "" {
t.Fatalf("unexpected file: %v", f)
}
if d.HasPrefix("/hey") {
t.Fatalf("should be false")
}
if !d.HasPrefix("/") {
t.Fatalf("/ should have the prefix /")
}
}
func TestHasPrefix_SlashFoo(t *testing.T) {
fSys := MakeFakeFS()
err := fSys.Mkdir("/foo")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
d, _, err := fSys.CleanedAbs("/foo")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if d.HasPrefix("/fo") {
t.Fatalf("/foo does not have path prefix /fo")
}
if d.HasPrefix("/fod") {
t.Fatalf("/foo does not have path prefix /fod")
}
if !d.HasPrefix("/foo") {
t.Fatalf("/foo should have prefix /foo")
}
}
func TestHasPrefix_SlashFooBar(t *testing.T) {
fSys := MakeFakeFS()
err := fSys.MkdirAll("/foo/bar")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
d, _, err := fSys.CleanedAbs("/foo/bar")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if d.HasPrefix("/fo") {
t.Fatalf("/foo/bar does not have path prefix /fo")
}
if d.HasPrefix("/foobar") {
t.Fatalf("/foo/bar does not have path prefix /foobar")
}
if !d.HasPrefix("/foo/bar") {
t.Fatalf("/foo/bar should have prefix /foo/bar")
}
if !d.HasPrefix("/foo") {
t.Fatalf("/foo/bar should have prefix /foo")
}
if !d.HasPrefix("/") {
t.Fatalf("/foo/bar should have prefix /")
}
}

View File

@@ -102,16 +102,16 @@ func (fs *fakeFs) Open(name string) (File, error) {
return fs.m[name], nil
}
// CleanedAbs does nothing and cannot fail.
func (fs *fakeFs) CleanedAbs(path string) (string, string, error) {
// CleanedAbs cannot fail.
func (fs *fakeFs) CleanedAbs(path string) (ConfirmedDir, string, error) {
if fs.IsDir(path) {
return path, "", nil
return ConfirmedDir(path), "", nil
}
d := filepath.Dir(path)
if d == path {
return d, "", nil
return ConfirmedDir(d), "", nil
}
return d, filepath.Base(path), nil
return ConfirmedDir(d), filepath.Base(path), nil
}
// Exists returns true if file is known.

View File

@@ -30,7 +30,7 @@ type FileSystem interface {
RemoveAll(name string) error
Open(name string) (File, error)
IsDir(name string) bool
CleanedAbs(path string) (string, string, error)
CleanedAbs(path string) (ConfirmedDir, string, error)
Exists(name string) bool
Glob(pattern string) ([]string, error)
ReadFile(name string) ([]byte, error)

View File

@@ -60,7 +60,8 @@ func (realFS) Open(name string) (File, error) { return os.Open(name) }
// and file components. If the entire path is
// a directory, the file component is an empty
// string.
func (x realFS) CleanedAbs(path string) (string, string, error) {
func (x realFS) CleanedAbs(
path string) (ConfirmedDir, string, error) {
absRoot, err := filepath.Abs(path)
if err != nil {
return "", "", fmt.Errorf(
@@ -72,7 +73,7 @@ func (x realFS) CleanedAbs(path string) (string, string, error) {
"evalsymlink failure on '%s' : %v", path, err)
}
if x.IsDir(deLinked) {
return deLinked, "", nil
return ConfirmedDir(deLinked), "", nil
}
d := filepath.Dir(deLinked)
if !x.IsDir(d) {
@@ -89,7 +90,7 @@ func (x realFS) CleanedAbs(path string) (string, string, error) {
log.Fatalf("these should be equal: '%s', '%s'",
filepath.Join(d, f), deLinked)
}
return d, f, nil
return ConfirmedDir(d), f, nil
}
// Exists returns true if os.Stat succeeds.

View File

@@ -52,7 +52,7 @@ func TestCleanedAbs_1(t *testing.T) {
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != wd {
if d.String() != wd {
t.Fatalf("unexpected d=%s", d)
}
if f != "" {
@@ -90,7 +90,7 @@ func TestCleanedAbs_3(t *testing.T) {
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != testDir {
if d.String() != testDir {
t.Fatalf("unexpected d=%s", d)
}
if f != "foo" {
@@ -119,7 +119,7 @@ func TestCleanedAbs_4(t *testing.T) {
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != filepath.Join(testDir, "d1", "d2") {
if d.String() != filepath.Join(testDir, "d1", "d2") {
t.Fatalf("unexpected d=%s", d)
}
if f != "" {
@@ -131,7 +131,7 @@ func TestCleanedAbs_4(t *testing.T) {
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != filepath.Join(testDir, "d1", "d2") {
if d.String() != filepath.Join(testDir, "d1", "d2") {
t.Fatalf("unexpected d=%s", d)
}
if f != "bar" {