Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fstest2 #1

Merged
merged 1 commit into from
Nov 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions fsdelegator.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ func (d *FileInfoDelegator) ModTime() time.Time {
return d.Values.ModTime
}

// IsDir returns d.Values.IsDir.
func (d *FileInfoDelegator) IsDir() bool {
return d.Values.IsDir
}
Expand Down
108 changes: 108 additions & 0 deletions fstest2/fstest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Package fstest2 implements support for testing implementations and users of file systems.
package fstest2

import (
"fmt"
"io/fs"
"strings"
"testing/iotest"

"github.com/jarxorg/fs2"
)

// TestWriteFileFS tests a fs2.WriteFileFS implementation.
//
// Typical usage inside a test is:
//
// tmpDir, err := ioutil.TempDir("", "test")
// if err != nil {
// t.Fatal(err)
// }
// defer os.RemoveAll(tmpDir)
//
// fsys := osfs.New(filepath.Dir(tmpDir))
// if err := fstest2.TestWriteFileFS(fsys, filepath.Base(tmpDir)); err != nil {
// t.Fatal(err)
// }
func TestWriteFileFS(fsys fs.FS, tmpDir string) error {
tests := []struct {
name string
wantErr bool
}{
{
name: "file.txt", // simple create file.
}, {
name: "dir/file.txt", // mkdir and create file.
}, {
name: "dir", // dir is exists that is a directory.
wantErr: true,
}, {
name: "dir/file.txt/invalid", // dir/file.txt is exists that is a file.
wantErr: true,
}, {
name: "file.txt/.", // invalid path.
wantErr: true,
}, {
name: "dir/file.txt", // update file.
},
}
for _, test := range tests {
name := tmpDir + "/" + test.name

f, err := fs2.CreateFile(fsys, name, fs.ModePerm)
if test.wantErr {
if err == nil {
f.Close()
return fmt.Errorf("%s: CreateFile returns no error", name)
}
continue
}
if err != nil {
return fmt.Errorf("%s: CreateFile: %v", name, err)
}

if err := checkFileWrite(fsys, f, name); err != nil {
return err
}
}
if err := fs2.RemoveFile(fsys, tmpDir+"/file.txt"); err != nil {
return fmt.Errorf("%s: RemoveFile: %v", "file.txt", err)
}
if err := fs2.RemoveAll(fsys, tmpDir+"/dir"); err != nil {
return fmt.Errorf("%s: RemoveAll: %v", "dir", err)
}
return nil
}

func checkFileWrite(fsys fs.FS, f fs2.WriterFile, name string) error {
ps := [][]byte{[]byte("hello"), []byte(",world")}
data := append(ps[0], ps[1]...)

nn := 0
for _, p := range ps {
n, err := f.Write(p)
if err != nil {
f.Close()
return fmt.Errorf("%s: WriterFile.Write: %v", name, err)
}
nn = nn + n
}

if err := f.Close(); err != nil {
return fmt.Errorf("%s: WriterFile.Close: %v", name, err)
}

if nn != len(data) {
return fmt.Errorf("%s: Write size got %d; want %d", name, nn, len(data))
}

r, err := fsys.Open(name)
if err != nil {
return fmt.Errorf("%s: Open: %v", name, err)
}
defer r.Close()
if err := iotest.TestReader(r, data); err != nil {
return fmt.Errorf("%s: failed TestReader:\n\t%s", name, strings.ReplaceAll(err.Error(), "\n", "\n\t"))
}
return nil
}
29 changes: 12 additions & 17 deletions memfs/memfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"bytes"
"io"
"io/fs"
"path/filepath"
"path"
"strings"
"sync"
"syscall"
Expand Down Expand Up @@ -41,7 +41,11 @@ func New() *MemFS {
}

func (fsys *MemFS) key(name string) string {
return filepath.Clean(filepath.Join(fsys.dir, name))
return path.Clean(path.Join(fsys.dir, name))
}

func (fsys *MemFS) rel(name string) string {
return strings.TrimPrefix(name, fsys.dir)
}

func (fsys *MemFS) open(name string) (*value, error) {
Expand All @@ -61,7 +65,7 @@ func (fsys *MemFS) mkdirAll(dir string, mode fs.FileMode) error {
}
keys := strings.Split(fsys.key(dir), "/")
for i, k := range keys {
key := fsys.key(filepath.Join(keys[0 : i+1]...))
key := fsys.key(path.Join(keys[0 : i+1]...))
if v := fsys.store.get(key); v != nil {
if !v.isDir {
return &fs.PathError{Op: "MkdirAll", Path: dir, Err: fs.ErrInvalid}
Expand All @@ -81,7 +85,7 @@ func (fsys *MemFS) create(name string, mode fs.FileMode) (*value, error) {
if !fs.ValidPath(name) {
return nil, &fs.PathError{Op: "Create", Path: name, Err: fs.ErrInvalid}
}
err := fsys.mkdirAll(filepath.Dir(name), mode)
err := fsys.mkdirAll(path.Dir(name), mode)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -117,10 +121,6 @@ func (fsys *MemFS) Open(name string) (fs.File, error) {
return f, nil
}

var filepathRel = func(basepath, targpath string) (string, error) {
return filepath.Rel(basepath, targpath)
}

// Glob returns the names of all files matching pattern, providing an implementation
// of the top-level Glob function.
func (fsys *MemFS) Glob(pattern string) ([]string, error) {
Expand All @@ -134,11 +134,7 @@ func (fsys *MemFS) Glob(pattern string) ([]string, error) {

var names []string
for _, key := range keys {
name, err := filepathRel(fsys.dir, key)
if err != nil {
return nil, err
}
names = append(names, name)
names = append(names, fsys.rel(key))
}
return names, nil
}
Expand Down Expand Up @@ -206,7 +202,7 @@ func (fsys *MemFS) Sub(dir string) (fs.FS, error) {
return nil, &fs.PathError{Op: "Sub", Path: dir, Err: fs.ErrInvalid}
}
return &MemFS{
dir: filepath.Join(fsys.dir, dir),
dir: path.Join(fsys.dir, dir),
store: fsys.store,
}, nil
}
Expand All @@ -224,14 +220,13 @@ func (fsys *MemFS) CreateFile(name string, mode fs.FileMode) (fs2.WriterFile, er
fsys.mutex.Lock()
defer fsys.mutex.Unlock()

v, err := fsys.create(name, mode)
if err != nil {
if _, err := fsys.create(name, mode); err != nil {
return nil, err
}
return &MemFile{
fsys: fsys,
name: name,
buf: bytes.NewBuffer(v.data),
buf: new(bytes.Buffer),
mode: mode,
}, nil
}
Expand Down
33 changes: 12 additions & 21 deletions memfs/memfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing/fstest"

"github.com/jarxorg/fs2"
"github.com/jarxorg/fs2/fstest2"
)

func newMemFSTest(t *testing.T) *MemFS {
Expand All @@ -24,12 +25,19 @@ func newMemFSTest(t *testing.T) *MemFS {

func TestFS(t *testing.T) {
fsys := newMemFSTest(t)

if err := fstest.TestFS(fsys, "dir0"); err != nil {
if err := fstest.TestFS(fsys, "dir0", "dir0/file01.txt"); err != nil {
t.Errorf(`Error testing/fstest: %+v`, err)
}
if err := fstest.TestFS(fsys, "dir0/file01.txt"); err != nil {
t.Errorf(`Error testing/fstest: %+v`, err)
}

func TestWriteFileFS(t *testing.T) {
fsys := New()
tmpdir := "tmpdir"
if err := fsys.mkdirAll(tmpdir, fs.ModePerm); err != nil {
t.Fatal(err)
}
if err := fstest2.TestWriteFileFS(fsys, tmpdir); err != nil {
t.Errorf(`Error fs2/fstest2: %+v`, err)
}
}

Expand Down Expand Up @@ -163,23 +171,6 @@ func TestGlob(t *testing.T) {
}
}

func TestGlob_filepathRelError(t *testing.T) {
orgFilepathRel := filepathRel
defer func() { filepathRel = orgFilepathRel }()

wantErr := errors.New("test")
filepathRel = func(basepath, targpath string) (string, error) {
return "", wantErr
}

fsys := newMemFSTest(t)
var gotErr error
_, gotErr = fsys.Glob("*")
if gotErr != wantErr {
t.Errorf(`Error Glob error got %v; want %v`, gotErr, wantErr)
}
}

func TestReadDir(t *testing.T) {
testCases := []struct {
want []string
Expand Down
19 changes: 16 additions & 3 deletions osfs/osfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,32 @@ import (
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"
"testing/fstest"

"github.com/jarxorg/fs2"
"github.com/jarxorg/fs2/fstest2"
)

func TestFS(t *testing.T) {
if err := fstest.TestFS(DirFS("testdata"), "dir0"); err != nil {
fsys := New("testdata")
if err := fstest.TestFS(fsys, "dir0", "dir0/file01.txt"); err != nil {
t.Errorf("Error testing/fstest: %+v", err)
}
if err := fstest.TestFS(DirFS("testdata"), "dir0/file01.txt"); err != nil {
t.Errorf("Error testing/fstest: %+v", err)
}

func TestWriteFileFS(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)

fsys := New(filepath.Dir(tmpDir))
if err := fstest2.TestWriteFileFS(fsys, filepath.Base(tmpDir)); err != nil {
t.Errorf(`Error fs2/fstest2: %+v`, err)
}
}

Expand Down