package test
import (
"bytes"
"errors"
"io"
"os"
"path/filepath"
"strings"
"sync"
)
// FakeFileSystem provides a fake filesystem structure for testing
type FakeFileSystem struct {
ChmodFile []string
ChmodMode os.FileMode
ChmodError map[string]error
RenameFrom string
RenameTo string
RenameError error
MkdirAllDir []string
MkdirAllError error
MkdirDir string
MkdirError error
ExistsFile []string
ExistsResult map[string]bool
CopySource string
CopyDest string
CopyError error
RemoveDirName string
RemoveDirError error
WorkingDirCalled bool
WorkingDirResult string
WorkingDirError error
OpenFile string
OpenFileResult *FakeReadCloser
OpenContent string
OpenError error
OpenCloseError error
WriteFileName string
WriteFileError error
WriteFileContent string
Files []os.FileInfo
mutex sync.Mutex
}
// FakeReadCloser provider a fake ReadCloser
type FakeReadCloser struct {
*bytes.Buffer
CloseCalled bool
CloseError error
}
// Close closes the fake ReadCloser
func (f *FakeReadCloser) Close() error {
f.CloseCalled = true
return f.CloseError
}
// ReadDir reads the files in specified directory
func (f *FakeFileSystem) ReadDir(p string) ([]os.FileInfo, error) {
return f.Files, nil
}
// Stat provides stats about a single file
func (f *FakeFileSystem) Stat(p string) (os.FileInfo, error) {
for _, f := range f.Files {
if strings.HasSuffix(p, string(filepath.Separator)+f.Name()) {
return f, nil
}
}
return nil, &os.PathError{Path: p, Err: errors.New("file does not exist")}
}
// Chmod manipulates permissions on the fake filesystem
func (f *FakeFileSystem) Chmod(file string, mode os.FileMode) error {
f.mutex.Lock()
defer f.mutex.Unlock()
f.ChmodFile = append(f.ChmodFile, file)
f.ChmodMode = mode
return f.ChmodError[file]
}
// Rename renames files on the fake filesystem
func (f *FakeFileSystem) Rename(from, to string) error {
f.RenameFrom = from
f.RenameTo = to
return f.RenameError
}
// MkdirAll creates a new directories on the fake filesystem
func (f *FakeFileSystem) MkdirAll(dirname string) error {
f.MkdirAllDir = append(f.MkdirAllDir, dirname)
return f.MkdirAllError
}
// Mkdir creates a new directory on the fake filesystem
func (f *FakeFileSystem) Mkdir(dirname string) error {
f.MkdirDir = dirname
return f.MkdirError
}
// Exists checks if the file exists in fake filesystem
func (f *FakeFileSystem) Exists(file string) bool {
f.ExistsFile = append(f.ExistsFile, file)
return f.ExistsResult[file]
}
// Copy copies files on the fake filesystem
func (f *FakeFileSystem) Copy(sourcePath, targetPath string) error {
f.CopySource = sourcePath
f.CopyDest = targetPath
return f.CopyError
}
// CopyContents copies directory contents on the fake filesystem
func (f *FakeFileSystem) CopyContents(sourcePath, targetPath string) error {
f.CopySource = sourcePath
f.CopyDest = targetPath
return f.CopyError
}
// RemoveDirectory removes a directory in the fake filesystem
func (f *FakeFileSystem) RemoveDirectory(dir string) error {
f.RemoveDirName = dir
return f.RemoveDirError
}
// CreateWorkingDirectory creates a fake working directory
func (f *FakeFileSystem) CreateWorkingDirectory() (string, error) {
f.WorkingDirCalled = true
return f.WorkingDirResult, f.WorkingDirError
}
// Open opens a file
func (f *FakeFileSystem) Open(file string) (io.ReadCloser, error) {
f.OpenFile = file
buf := bytes.NewBufferString(f.OpenContent)
f.OpenFileResult = &FakeReadCloser{
Buffer: buf,
CloseError: f.OpenCloseError,
}
return f.OpenFileResult, f.OpenError
}
// WriteFile writes a file
func (f *FakeFileSystem) WriteFile(file string, data []byte) error {
f.WriteFileName = file
f.WriteFileContent = string(data)
return f.WriteFileError
}
// Walk walks the file tree rooted at root, calling walkFn for each file or
// directory in the tree, including root.
func (f *FakeFileSystem) Walk(root string, walkFn filepath.WalkFunc) error {
return filepath.Walk(root, walkFn)
}