Commit Diff


commit - 10e7bb7102d22bf8c385dedeb7efd4c3b1e2a128
commit + d731b8751b28b6b520debb1eb334a67bf1a0df5d
blob - 5c66b21f2af9716a8dde2f936f9bc6d162a9ec2e
blob + dd2268f373ca1c18582138aa683f20efee4b2e1e
--- vfs.go
+++ vfs.go
@@ -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) e
 	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{
blob - /dev/null
blob + 5c8e080d341b73f05781f6d1688ca2c3c81a51df (mode 644)
--- /dev/null
+++ mockfile.go
@@ -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
+}
blob - fcf03e0d395795eee9a02a0fc5ef1fc83b45a867
blob + f9798ea716c4a97b5630e85b72f900ee49b2858f
--- vfs_test.go
+++ vfs_test.go
@@ -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)
+}