add mockfile that holds a size instead of data

This commit is contained in:
Evan Burkey 2023-07-27 15:56:09 -07:00
parent 10e7bb7102
commit d731b8751b
3 changed files with 127 additions and 3 deletions

43
mockfile.go Normal file
View File

@ -0,0 +1,43 @@
package vfs
import (
"io/fs"
"os"
"time"
)
type MockFile struct {
name string
mode os.FileMode
modified time.Time
open bool
size int64
}
func (f *MockFile) Stat() (fs.FileInfo, error) {
if f.open {
return &fileInfo{
name: f.name,
size: f.size,
modified: f.modified,
mode: f.mode,
}, nil
}
return nil, fs.ErrClosed
}
func (f *MockFile) Read(data []byte) (int, error) {
if f.open {
data = []byte{}
return 0, nil
}
return 0, fs.ErrClosed
}
func (f *MockFile) Close() error {
if f.open {
f.open = false
return nil
}
return fs.ErrClosed
}

68
vfs.go
View File

@ -42,17 +42,24 @@ func (f *FS) Open(path string) (fs.File, error) {
switch c := child.(type) {
case *File:
fp := &File{
return &File{
name: c.name,
mode: c.mode,
data: bytes.NewBuffer(c.data.Bytes()),
open: true,
}
return fp, nil
}, nil
case *directory:
return &directoryHandle{
dir: c,
}, nil
case *MockFile:
return &MockFile{
name: c.name,
mode: c.mode,
modified: c.modified,
open: true,
size: c.size,
}, nil
}
return nil, fmt.Errorf("%s is unknown file type %v", path, fs.ErrInvalid)
@ -87,6 +94,13 @@ func (f *FS) find(path string) (interface{}, error) {
return nil, fmt.Errorf("%s does not exist", path)
}
if _, ok := child.(*MockFile); ok {
if i == len(split)-1 {
return child, nil
}
return nil, fmt.Errorf("%s does not exist", path)
}
if subdir, ok := child.(*directory); !ok {
return nil, fmt.Errorf("directory %s does not exist", path)
} else {
@ -218,6 +232,54 @@ func (f *FS) MkdirAll(path string, mode os.FileMode) error {
return nil
}
func (f *FS) CreateMockFile(fpath string, size int64, mode os.FileMode) error {
if !fs.ValidPath(fpath) {
return &fs.PathError{
Op: "WriteFile",
Path: fpath,
Err: fs.ErrInvalid,
}
}
if fpath == "." {
fpath = ""
}
err := func() error {
dirName, fileName := path.Split(fpath)
dirName = strings.TrimSuffix(dirName, "/")
dir, err := f.findDirectory(dirName)
if err != nil {
return err
}
dir.mutex.Lock()
defer dir.mutex.Unlock()
checkExist := dir.children[fileName]
if checkExist != nil {
if _, ok := checkExist.(*File); !ok {
return fmt.Errorf("%s is a directory that already exists", fpath)
}
}
file := &MockFile{
name: fileName,
mode: 0666,
size: size,
}
dir.children[fileName] = file
return nil
}()
if err != nil {
return err
}
return nil
}
func (f *FS) WriteFile(path string, data []byte, mode os.FileMode) error {
if !fs.ValidPath(path) {
return &fs.PathError{

View File

@ -41,3 +41,22 @@ func TestVFS_Basic(t *testing.T) {
assert.NoError(t, err)
}
}
func TestVFS_MockFile(t *testing.T) {
vfs := NewVFS()
path := "test.txt"
sz := int64(8096)
err := vfs.CreateMockFile(path, sz, 0666)
assert.NoError(t, err)
fp, err := vfs.Open(path)
assert.NoError(t, err)
stat, err := fp.Stat()
assert.NoError(t, err)
assert.Equal(t, stat.Size(), sz)
err = fp.Close()
assert.NoError(t, err)
}