Skip to content

Commit

Permalink
Prevent test failures on Windows, address feedback from pjbgf
Browse files Browse the repository at this point in the history
  • Loading branch information
evankanderson committed Sep 22, 2024
1 parent 28f6c49 commit b8c5b1b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
32 changes: 15 additions & 17 deletions helper/iofs/iofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ type adapterFs struct {
fs billyfs.Filesystem
}

// Type assertion that adapterFS implements the following interfaces:
var _ fs.FS = (*adapterFs)(nil)
var _ fs.ReadDirFS = (*adapterFs)(nil)
var _ fs.StatFS = (*adapterFs)(nil)
var _ fs.ReadFileFS = (*adapterFs)(nil)

// GlobFS would be harder, we don't implement for now.
// TODO: implement fs.GlobFS, which will be a fair bit more code.

// Open implements fs.FS.
// Open opens the named file on the underlying FS, implementing fs.FS (returning a file or error).
func (a *adapterFs) Open(name string) (fs.File, error) {
if name[0] == '/' || name != filepath.Clean(name) {
// fstest.TestFS explicitly checks that these should return error
// MemFS is performs the clean internally, so we need to block that here for testing.
// fstest.TestFS explicitly checks that these should return error.
// MemFS performs the clean internally, so we need to block that here for testing purposes.
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
}
stat, err := a.fs.Stat(name)
Expand All @@ -49,7 +50,7 @@ func (a *adapterFs) Open(name string) (fs.File, error) {
return &adapterFile{file: file, info: stat}, err
}

// ReadDir implements fs.ReadDirFS.
// ReadDir reads the named directory, implementing fs.ReadDirFS (returning a listing or error).
func (a *adapterFs) ReadDir(name string) ([]fs.DirEntry, error) {
items, err := a.fs.ReadDir(name)
if err != nil {
Expand All @@ -62,12 +63,12 @@ func (a *adapterFs) ReadDir(name string) ([]fs.DirEntry, error) {
return entries, nil
}

// Stat implements fs.StatFS.
// Stat returns information on the named file, implementing fs.StatFS (returning FileInfo or error).
func (a *adapterFs) Stat(name string) (fs.FileInfo, error) {
return a.fs.Stat(name)
}

// ReadFile implements fs.ReadFileFS.
// ReadFile reads the named file and returns its contents, implementing fs.ReadFileFS (returning contents or error).
func (a *adapterFs) ReadFile(name string) ([]byte, error) {
stat, err := a.fs.Stat(name)
if err != nil {
Expand All @@ -90,17 +91,17 @@ type adapterFile struct {

var _ fs.File = (*adapterFile)(nil)

// Close implements fs.File.
// Close closes the file, implementing fs.File (and io.Closer).
func (a *adapterFile) Close() error {
return a.file.Close()
}

// Read implements fs.File.
// Read reads bytes from the file, implementing fs.File (and io.Reader).
func (a *adapterFile) Read(b []byte) (int, error) {
return a.file.Read(b)
}

// Stat implements fs.File.
// Stat returns file information, implementing fs.File (returning FileInfo or error).
func (a *adapterFile) Stat() (fs.FileInfo, error) {
return a.info, nil
}
Expand All @@ -119,24 +120,21 @@ func makeDir(stat fs.FileInfo, entries []fs.DirEntry) *adapterDirFile {
}
}

// Close implements fs.File.
// Close closes the directory, implementing fs.File (and io.Closer).
// Subtle: note that this is shadowing adapterFile.Close.
func (a *adapterDirFile) Close() error {
return nil
}

// ReadDir implements fs.ReadDirFile.
// ReadDir reads the directory contents, implementing fs.ReadDirFile (returning directory listing or error).
func (a *adapterDirFile) ReadDir(n int) ([]fs.DirEntry, error) {
if len(a.entries) == 0 && n > 0 {
return nil, io.EOF
}
if n <= 0 {
n = len(a.entries)
}
if n > len(a.entries) {
if n <= 0 || n > len(a.entries) {
n = len(a.entries)
}
entries := a.entries[:n]
a.entries = a.entries[n:]
return entries, nil
}
}
12 changes: 8 additions & 4 deletions helper/iofs/iofs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,27 @@ type wrappedError interface {
Unwrap() error
}

// TestWithFSTest leverages the packaged Go fstest package, which seems comprehensive
// TestWithFSTest leverages the packaged Go fstest package, which seems comprehensive.
func TestWithFSTest(t *testing.T) {
t.Parallel()
memfs := memfs.New()
iofs := Wrap(memfs)

files := map[string]string{
"foo.txt": "hello, world",
"bar.txt": "goodbye, world",
"dir/baz.txt": "こんにちわ, world",
"foo.txt": "hello, world",
"bar.txt": "goodbye, world",
filepath.Join("dir", "baz.txt"): "こんにちわ, world",
}
created_files := make([]string, 0, len(files))
for filename, contents := range files {
makeFile(memfs, t, filename, contents)
created_files = append(created_files, filename)
}

if runtime.GOOS == "windows" {
t.Skip("fstest.TestFS is not yet windows path aware")
}

err := fstest.TestFS(iofs, created_files...)
if err != nil {
checkFsTestError(t, err, files)
Expand Down

0 comments on commit b8c5b1b

Please sign in to comment.