mirror of https://github.com/markbates/pkger.git
this stolen feeling!
This commit is contained in:
parent
91ee10f16b
commit
704b38d3ea
26
fs/fs.go
26
fs/fs.go
|
@ -8,13 +8,31 @@ import (
|
|||
)
|
||||
|
||||
type FileSystem interface {
|
||||
Create(name string) (File, error)
|
||||
Parse(p string) (Path, error)
|
||||
Current() (here.Info, error)
|
||||
Info(p string) (here.Info, error)
|
||||
MkdirAll(p string, perm os.FileMode) error
|
||||
Open(name string) (File, error)
|
||||
Parse(p string) (Path, error)
|
||||
|
||||
// ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported.
|
||||
ReadFile(s string) ([]byte, error)
|
||||
|
||||
// Create creates the named file with mode 0666 (before umask) - It's actually 0644, truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR.
|
||||
Create(name string) (File, error)
|
||||
|
||||
// MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm (before umask) are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.
|
||||
MkdirAll(p string, perm os.FileMode) error
|
||||
|
||||
// Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY.
|
||||
Open(name string) (File, error)
|
||||
|
||||
// Stat returns a FileInfo describing the named file.
|
||||
Stat(name string) (os.FileInfo, error)
|
||||
|
||||
// Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which makes the output deterministic but means that for very large directories Walk can be inefficient. Walk does not follow symbolic links. - That is from the standard library. I know. Their grammar teachers can not be happy with them right now.
|
||||
Walk(p string, wf filepath.WalkFunc) error
|
||||
|
||||
// Remove removes the named file or (empty) directory.
|
||||
Remove(name string) error
|
||||
|
||||
// RemoveAll removes path and any children it contains. It removes everything it can but returns the first error it encounters. If the path does not exist, RemoveAll returns nil (no error).
|
||||
RemoveAll(path string) error
|
||||
}
|
||||
|
|
|
@ -1,37 +1,12 @@
|
|||
package fstest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/markbates/pkger/fs"
|
||||
)
|
||||
|
||||
type TestFile struct {
|
||||
Name string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (t TestFile) Create(fx fs.FileSystem) error {
|
||||
f, err := fx.Create(t.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(f, bytes.NewReader(t.Data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
Path fs.Path
|
||||
}
|
||||
|
||||
type TestFiles map[string]TestFile
|
||||
|
||||
func (t TestFiles) Create(fx fs.FileSystem) error {
|
||||
for k, f := range t {
|
||||
f.Name = k
|
||||
if err := f.Create(fx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package fstest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/markbates/pkger/fs"
|
||||
)
|
||||
|
||||
func Files(fx fs.FileSystem) (TestFiles, error) {
|
||||
info, err := fx.Current()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tf := TestFiles{}
|
||||
for _, f := range fileList {
|
||||
name := Path(fx, f)
|
||||
tf[name] = TestFile{
|
||||
Name: name,
|
||||
Path: fs.Path{
|
||||
Pkg: info.ImportPath,
|
||||
Name: name,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return tf, nil
|
||||
}
|
||||
|
||||
func Path(fx fs.FileSystem, ps ...string) string {
|
||||
name := path.Join("/.fstest", fmt.Sprintf("%T", fx))
|
||||
name = path.Join(name, strings.Join(ps, "/"))
|
||||
return name
|
||||
}
|
||||
|
||||
var fileList = []string{
|
||||
"/main.go",
|
||||
"/go.mod",
|
||||
"/go.sum",
|
||||
"/public/index.html",
|
||||
"/public/images/mark.png",
|
||||
"/templates/a.txt",
|
||||
"/templates/b/b.txt",
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package fstest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger/fs"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type FileSystem struct {
|
||||
FS fs.FileSystem
|
||||
}
|
||||
|
||||
func NewFileSystem(yourfs fs.FileSystem) (*FileSystem, error) {
|
||||
suite := &FileSystem{
|
||||
FS: yourfs,
|
||||
}
|
||||
return suite, nil
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test(t *testing.T) {
|
||||
rv := reflect.ValueOf(s)
|
||||
rt := rv.Type()
|
||||
if rt.NumMethod() == 0 {
|
||||
t.Fatalf("something went wrong wrong with %s %T", s, s)
|
||||
}
|
||||
for i := 0; i < rt.NumMethod(); i++ {
|
||||
m := rt.Method(i)
|
||||
if !strings.HasPrefix(m.Name, "Test_") {
|
||||
continue
|
||||
}
|
||||
s.sub(t, m)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileSystem) sub(t *testing.T, m reflect.Method) {
|
||||
name := strings.TrimPrefix(m.Name, "Test_")
|
||||
name = fmt.Sprintf("%T_%s", s.FS, name)
|
||||
t.Run(name, func(st *testing.T) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
st.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
cleaner := func() {
|
||||
if err := s.Clean(); err != nil {
|
||||
st.Fatal(err)
|
||||
}
|
||||
}
|
||||
cleaner()
|
||||
|
||||
defer cleaner()
|
||||
m.Func.Call([]reflect.Value{
|
||||
reflect.ValueOf(s),
|
||||
reflect.ValueOf(st),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *FileSystem) Clean() error {
|
||||
name := Path(s.FS)
|
||||
err := s.FS.RemoveAll(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := s.FS.Stat(name); err == nil {
|
||||
return fmt.Errorf("expected %q to be, you know, not there any more", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Create(t *testing.T) {
|
||||
r := require.New(t)
|
||||
name := Path(s.FS, "i", "want", "candy.song")
|
||||
|
||||
f, err := s.FS.Create(name)
|
||||
r.NoError(err)
|
||||
r.Equal(name, f.Name())
|
||||
|
||||
fi, err := f.Stat()
|
||||
r.NoError(err)
|
||||
|
||||
r.Equal(name, fi.Name())
|
||||
r.Equal(os.FileMode(0644), fi.Mode())
|
||||
r.NotZero(fi.ModTime())
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Current(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Info(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_MkdirAll(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Open(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Parse(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_ReadFile(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Stat(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *FileSystem) Test_Walk(t *testing.T) {
|
||||
panic("not implemented")
|
||||
}
|
|
@ -69,7 +69,6 @@ func (f *FS) MkdirAll(p string, perm os.FileMode) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(">>>TODO fs/hdfs/hdfs.go:73: pp ", p)
|
||||
return os.MkdirAll(p, perm)
|
||||
}
|
||||
|
||||
|
@ -134,3 +133,19 @@ func (f *FS) Walk(p string, wf filepath.WalkFunc) error {
|
|||
func (f *FS) locate(p string) (string, error) {
|
||||
return f.current.FilePath(p), nil
|
||||
}
|
||||
|
||||
func (fx *FS) Remove(name string) error {
|
||||
name, err := fx.locate(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Remove(name)
|
||||
}
|
||||
|
||||
func (fx *FS) RemoveAll(name string) error {
|
||||
name, err := fx.locate(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.RemoveAll(name)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package hdfs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger/fs/fstest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_FS(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
myfs, err := New()
|
||||
r.NoError(err)
|
||||
|
||||
suite, err := fstest.NewFileSystem(myfs)
|
||||
r.NoError(err)
|
||||
|
||||
suite.Test(t)
|
||||
}
|
|
@ -23,7 +23,7 @@ func (fx *FS) Create(name string) (fs.File, error) {
|
|||
info: &fs.FileInfo{
|
||||
Details: fs.Details{
|
||||
Name: pt.Name,
|
||||
Mode: 0666,
|
||||
Mode: 0644,
|
||||
ModTime: fs.ModTime(time.Now()),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,90 +1,80 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger/here"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Create(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs, err := New(here.Info{})
|
||||
f, err := fs.Create("/hello.txt")
|
||||
r.NoError(err)
|
||||
r.NotNil(f)
|
||||
|
||||
fi, err := f.Stat()
|
||||
r.NoError(err)
|
||||
|
||||
r.Equal("/hello.txt", fi.Name())
|
||||
r.Equal(os.FileMode(0666), fi.Mode())
|
||||
r.NotZero(fi.ModTime())
|
||||
}
|
||||
|
||||
func Test_Create_Write(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs, err := New(here.Info{})
|
||||
f, err := fs.Create("/hello.txt")
|
||||
r.NoError(err)
|
||||
r.NotNil(f)
|
||||
|
||||
fi, err := f.Stat()
|
||||
r.NoError(err)
|
||||
r.Zero(fi.Size())
|
||||
|
||||
r.Equal("/hello.txt", fi.Name())
|
||||
|
||||
mt := fi.ModTime()
|
||||
r.NotZero(mt)
|
||||
|
||||
sz, err := io.Copy(f, strings.NewReader(radio))
|
||||
r.NoError(err)
|
||||
r.Equal(int64(1381), sz)
|
||||
|
||||
r.NoError(f.Close())
|
||||
r.Equal(int64(1381), fi.Size())
|
||||
r.NotZero(fi.ModTime())
|
||||
r.NotEqual(mt, fi.ModTime())
|
||||
}
|
||||
|
||||
const radio = `I was tuning in the shine on the late night dial
|
||||
Doing anything my radio advised
|
||||
With every one of those late night stations
|
||||
Playing songs bringing tears to my eyes
|
||||
I was seriously thinking about hiding the receiver
|
||||
When the switch broke 'cause it's old
|
||||
They're saying things that I can hardly believe
|
||||
They really think we're getting out of control
|
||||
Radio is a sound salvation
|
||||
Radio is cleaning up the nation
|
||||
They say you better listen to the voice of reason
|
||||
But they don't give you any choice 'cause they think that it's treason
|
||||
So you had better do as you are told
|
||||
You better listen to the radio
|
||||
I wanna bite the hand that feeds me
|
||||
I wanna bite that hand so badly
|
||||
I want to make them wish they'd never seen me
|
||||
Some of my friends sit around every evening
|
||||
And they worry about the times ahead
|
||||
But everybody else is overwhelmed by indifference
|
||||
And the promise of an early bed
|
||||
You either shut up or get cut up; they don't wanna hear about it
|
||||
It's only inches on the reel-to-reel
|
||||
And the radio is in the hands of such a lot of fools
|
||||
Tryin' to anesthetize the way that you feel
|
||||
Radio is a sound salvation
|
||||
Radio is cleaning up the nation
|
||||
They say you better listen to the voice of reason
|
||||
But they don't give you any choice 'cause they think that it's treason
|
||||
So you had better do as you are told
|
||||
You better listen to the radio
|
||||
Wonderful radio
|
||||
Marvelous radio
|
||||
Wonderful radio
|
||||
Radio, radio`
|
||||
// func Test_Create(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs, err := New(here.Info{})
|
||||
// f, err := fs.Create("/hello.txt")
|
||||
// r.NoError(err)
|
||||
// r.NotNil(f)
|
||||
//
|
||||
// fi, err := f.Stat()
|
||||
// r.NoError(err)
|
||||
//
|
||||
// r.Equal("/hello.txt", fi.Name())
|
||||
// r.Equal(os.FileMode(0666), fi.Mode())
|
||||
// r.NotZero(fi.ModTime())
|
||||
// }
|
||||
//
|
||||
// func Test_Create_Write(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs, err := New(here.Info{})
|
||||
// f, err := fs.Create("/hello.txt")
|
||||
// r.NoError(err)
|
||||
// r.NotNil(f)
|
||||
//
|
||||
// fi, err := f.Stat()
|
||||
// r.NoError(err)
|
||||
// r.Zero(fi.Size())
|
||||
//
|
||||
// r.Equal("/hello.txt", fi.Name())
|
||||
//
|
||||
// mt := fi.ModTime()
|
||||
// r.NotZero(mt)
|
||||
//
|
||||
// sz, err := io.Copy(f, strings.NewReader(radio))
|
||||
// r.NoError(err)
|
||||
// r.Equal(int64(1381), sz)
|
||||
//
|
||||
// r.NoError(f.Close())
|
||||
// r.Equal(int64(1381), fi.Size())
|
||||
// r.NotZero(fi.ModTime())
|
||||
// r.NotEqual(mt, fi.ModTime())
|
||||
// }
|
||||
//
|
||||
// const radio = `I was tuning in the shine on the late night dial
|
||||
// Doing anything my radio advised
|
||||
// With every one of those late night stations
|
||||
// Playing songs bringing tears to my eyes
|
||||
// I was seriously thinking about hiding the receiver
|
||||
// When the switch broke 'cause it's old
|
||||
// They're saying things that I can hardly believe
|
||||
// They really think we're getting out of control
|
||||
// Radio is a sound salvation
|
||||
// Radio is cleaning up the nation
|
||||
// They say you better listen to the voice of reason
|
||||
// But they don't give you any choice 'cause they think that it's treason
|
||||
// So you had better do as you are told
|
||||
// You better listen to the radio
|
||||
// I wanna bite the hand that feeds me
|
||||
// I wanna bite that hand so badly
|
||||
// I want to make them wish they'd never seen me
|
||||
// Some of my friends sit around every evening
|
||||
// And they worry about the times ahead
|
||||
// But everybody else is overwhelmed by indifference
|
||||
// And the promise of an early bed
|
||||
// You either shut up or get cut up; they don't wanna hear about it
|
||||
// It's only inches on the reel-to-reel
|
||||
// And the radio is in the hands of such a lot of fools
|
||||
// Tryin' to anesthetize the way that you feel
|
||||
// Radio is a sound salvation
|
||||
// Radio is cleaning up the nation
|
||||
// They say you better listen to the voice of reason
|
||||
// But they don't give you any choice 'cause they think that it's treason
|
||||
// So you had better do as you are told
|
||||
// You better listen to the radio
|
||||
// Wonderful radio
|
||||
// Marvelous radio
|
||||
// Wonderful radio
|
||||
// Radio, radio`
|
||||
|
|
|
@ -1,70 +1,58 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/markbates/pkger/here"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_File_Read_Memory(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs, err := New(here.Info{})
|
||||
r.NoError(err)
|
||||
|
||||
f, err := fs.Create("/file_test.go")
|
||||
r.NoError(err)
|
||||
_, err = io.Copy(f, bytes.NewReader([]byte("hi!")))
|
||||
r.NoError(err)
|
||||
r.NoError(f.Close())
|
||||
|
||||
f, err = fs.Open("/file_test.go")
|
||||
r.NoError(err)
|
||||
fi, err := f.Stat()
|
||||
r.NoError(err)
|
||||
r.Equal("/file_test.go", fi.Name())
|
||||
|
||||
b, err := ioutil.ReadAll(f)
|
||||
r.NoError(err)
|
||||
r.Equal(string(b), "hi!")
|
||||
}
|
||||
|
||||
func Test_File_Write(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs, err := New(here.Info{})
|
||||
r.NoError(err)
|
||||
|
||||
f, err := fs.Create("/hello.txt")
|
||||
r.NoError(err)
|
||||
r.NotNil(f)
|
||||
|
||||
fi, err := f.Stat()
|
||||
r.NoError(err)
|
||||
r.Zero(fi.Size())
|
||||
|
||||
r.Equal("/hello.txt", fi.Name())
|
||||
|
||||
mt := fi.ModTime()
|
||||
r.NotZero(mt)
|
||||
|
||||
sz, err := io.Copy(f, strings.NewReader(radio))
|
||||
r.NoError(err)
|
||||
r.Equal(int64(1381), sz)
|
||||
|
||||
// because windows can't handle the time precisely
|
||||
// enough, we have to *force* just a smidge of time
|
||||
// to ensure the two ModTime's are different.
|
||||
// i know, i hate it too.
|
||||
time.Sleep(time.Millisecond)
|
||||
r.NoError(f.Close())
|
||||
r.Equal(int64(1381), fi.Size())
|
||||
r.NotZero(fi.ModTime())
|
||||
r.NotEqual(mt, fi.ModTime())
|
||||
}
|
||||
// func Test_File_Read_Memory(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs, err := New(here.Info{})
|
||||
// r.NoError(err)
|
||||
//
|
||||
// f, err := fs.Create("/file_test.go")
|
||||
// r.NoError(err)
|
||||
// _, err = io.Copy(f, bytes.NewReader([]byte("hi!")))
|
||||
// r.NoError(err)
|
||||
// r.NoError(f.Close())
|
||||
//
|
||||
// f, err = fs.Open("/file_test.go")
|
||||
// r.NoError(err)
|
||||
// fi, err := f.Stat()
|
||||
// r.NoError(err)
|
||||
// r.Equal("/file_test.go", fi.Name())
|
||||
//
|
||||
// b, err := ioutil.ReadAll(f)
|
||||
// r.NoError(err)
|
||||
// r.Equal(string(b), "hi!")
|
||||
// }
|
||||
//
|
||||
// func Test_File_Write(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs, err := New(here.Info{})
|
||||
// r.NoError(err)
|
||||
//
|
||||
// f, err := fs.Create("/hello.txt")
|
||||
// r.NoError(err)
|
||||
// r.NotNil(f)
|
||||
//
|
||||
// fi, err := f.Stat()
|
||||
// r.NoError(err)
|
||||
// r.Zero(fi.Size())
|
||||
//
|
||||
// r.Equal("/hello.txt", fi.Name())
|
||||
//
|
||||
// mt := fi.ModTime()
|
||||
// r.NotZero(mt)
|
||||
//
|
||||
// sz, err := io.Copy(f, strings.NewReader(radio))
|
||||
// r.NoError(err)
|
||||
// r.Equal(int64(1381), sz)
|
||||
//
|
||||
// // because windows can't handle the time precisely
|
||||
// // enough, we have to *force* just a smidge of time
|
||||
// // to ensure the two ModTime's are different.
|
||||
// // i know, i hate it too.
|
||||
// time.Sleep(time.Millisecond)
|
||||
// r.NoError(f.Close())
|
||||
// r.Equal(int64(1381), fi.Size())
|
||||
// r.NotZero(fi.ModTime())
|
||||
// r.NotEqual(mt, fi.ModTime())
|
||||
// }
|
||||
|
|
|
@ -1,84 +1,75 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_HTTP_Dir(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs := NewFS()
|
||||
|
||||
r.NoError(Folder.Create(fs))
|
||||
|
||||
dir, err := fs.Open("/")
|
||||
r.NoError(err)
|
||||
ts := httptest.NewServer(http.FileServer(dir))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(res.Body)
|
||||
r.NoError(err)
|
||||
r.Contains(string(b), `<a href="/public/images/mark.png">/public/images/mark.png</a>`)
|
||||
}
|
||||
|
||||
func Test_HTTP_File_Memory(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs := NewFS()
|
||||
r.NoError(Folder.Create(fs))
|
||||
|
||||
dir, err := fs.Open("/")
|
||||
r.NoError(err)
|
||||
ts := httptest.NewServer(http.FileServer(dir))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/public/images/mark.png")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(res.Body)
|
||||
r.NoError(err)
|
||||
r.Contains(string(b), `!/public/images/mark.png`)
|
||||
}
|
||||
|
||||
func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs := NewFS()
|
||||
r.NoError(Folder.Create(fs))
|
||||
|
||||
dir, err := fs.Open("/public")
|
||||
r.NoError(err)
|
||||
defer dir.Close()
|
||||
|
||||
ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir)))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/assets/images/mark.png")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), "!/public/images/mark.png")
|
||||
|
||||
res, err = http.Get(ts.URL + "/assets/images/")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ = ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), `<a href="/mark.png">/mark.png</a>`)
|
||||
r.NotContains(string(b), `/public`)
|
||||
r.NotContains(string(b), `/images`)
|
||||
r.NotContains(string(b), `/go.mod`)
|
||||
}
|
||||
// func Test_HTTP_Dir(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs := NewFS()
|
||||
//
|
||||
// r.NoError(Folder.Create(fs))
|
||||
//
|
||||
// dir, err := fs.Open("/")
|
||||
// r.NoError(err)
|
||||
// ts := httptest.NewServer(http.FileServer(dir))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, err := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
// r.Contains(string(b), `<a href="/public/images/mark.png">/public/images/mark.png</a>`)
|
||||
// }
|
||||
//
|
||||
// func Test_HTTP_File_Memory(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs := NewFS()
|
||||
// r.NoError(Folder.Create(fs))
|
||||
//
|
||||
// dir, err := fs.Open("/")
|
||||
// r.NoError(err)
|
||||
// ts := httptest.NewServer(http.FileServer(dir))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/public/images/mark.png")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, err := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
// r.Contains(string(b), `!/public/images/mark.png`)
|
||||
// }
|
||||
//
|
||||
// func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs := NewFS()
|
||||
// r.NoError(Folder.Create(fs))
|
||||
//
|
||||
// dir, err := fs.Open("/public")
|
||||
// r.NoError(err)
|
||||
// defer dir.Close()
|
||||
//
|
||||
// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir)))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/assets/images/mark.png")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ := ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), "!/public/images/mark.png")
|
||||
//
|
||||
// res, err = http.Get(ts.URL + "/assets/images/")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ = ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), `<a href="/mark.png">/mark.png</a>`)
|
||||
// r.NotContains(string(b), `/public`)
|
||||
// r.NotContains(string(b), `/images`)
|
||||
// r.NotContains(string(b), `/go.mod`)
|
||||
// }
|
||||
|
|
|
@ -1,43 +1,33 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger/here"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_File_JSON(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs, err := New(here.Info{})
|
||||
r.NoError(err)
|
||||
|
||||
f, err := fs.Create("/radio.radio")
|
||||
r.NoError(err)
|
||||
_, err = io.Copy(f, strings.NewReader(radio))
|
||||
r.NoError(err)
|
||||
r.NoError(f.Close())
|
||||
|
||||
f, err = fs.Open("/radio.radio")
|
||||
r.NoError(err)
|
||||
bi, err := f.Stat()
|
||||
r.NoError(err)
|
||||
|
||||
mj, err := json.Marshal(f)
|
||||
r.NoError(err)
|
||||
|
||||
f2 := &File{}
|
||||
|
||||
r.NoError(json.Unmarshal(mj, f2))
|
||||
|
||||
ai, err := f2.Stat()
|
||||
r.NoError(err)
|
||||
|
||||
r.Equal(bi.Size(), ai.Size())
|
||||
|
||||
r.Equal(radio, string(f2.data))
|
||||
}
|
||||
// func Test_File_JSON(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs, err := New(here.Info{})
|
||||
// r.NoError(err)
|
||||
//
|
||||
// f, err := fs.Create("/radio.radio")
|
||||
// r.NoError(err)
|
||||
// _, err = io.Copy(f, strings.NewReader(radio))
|
||||
// r.NoError(err)
|
||||
// r.NoError(f.Close())
|
||||
//
|
||||
// f, err = fs.Open("/radio.radio")
|
||||
// r.NoError(err)
|
||||
// bi, err := f.Stat()
|
||||
// r.NoError(err)
|
||||
//
|
||||
// mj, err := json.Marshal(f)
|
||||
// r.NoError(err)
|
||||
//
|
||||
// f2 := &File{}
|
||||
//
|
||||
// r.NoError(json.Unmarshal(mj, f2))
|
||||
//
|
||||
// ai, err := f2.Stat()
|
||||
// r.NoError(err)
|
||||
//
|
||||
// r.Equal(bi.Size(), ai.Size())
|
||||
//
|
||||
// r.Equal(radio, string(f2.data))
|
||||
// }
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/markbates/pkger/fs"
|
||||
"github.com/markbates/pkger/here"
|
||||
|
@ -56,3 +59,47 @@ func (fx *FS) ReadFile(s string) ([]byte, error) {
|
|||
defer f.Close()
|
||||
return ioutil.ReadAll(f)
|
||||
}
|
||||
|
||||
func (fx *FS) Remove(name string) error {
|
||||
pt, err := fx.Parse(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := fx.files.Load(pt); !ok {
|
||||
return &os.PathError{"remove", pt.String(), fmt.Errorf("no such file or directory")}
|
||||
}
|
||||
|
||||
fx.files.Delete(pt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fx *FS) RemoveAll(name string) error {
|
||||
pt, err := fx.Parse(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fx.Walk("/", func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(path, pt.String()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
ph, err := fx.Parse(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fx.files.Delete(ph)
|
||||
return nil
|
||||
})
|
||||
if _, ok := fx.files.Load(pt); !ok {
|
||||
return &os.PathError{"remove", pt.String(), fmt.Errorf("no such file or directory")}
|
||||
}
|
||||
|
||||
fx.files.Delete(pt)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger/fs/fstest"
|
||||
"github.com/markbates/pkger/here"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func NewFS() *FS {
|
||||
fs, err := New(here.Info{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return fs
|
||||
}
|
||||
func Test_FS(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
var Folder = fstest.TestFiles{
|
||||
"/main.go": {Data: []byte("!/main.go")},
|
||||
"/go.mod": {Data: []byte("!/go.mod")},
|
||||
"/go.sum": {Data: []byte("!/go.sum")},
|
||||
"/public/index.html": {Data: []byte("!/public/index.html")},
|
||||
"/public/images/mark.png": {Data: []byte("!/public/images/mark.png")},
|
||||
"/templates/a.txt": {Data: []byte("!/templates/a.txt")},
|
||||
"/templates/b/b.txt": {Data: []byte("!/templates/b/b.txt")},
|
||||
info, err := here.Current()
|
||||
r.NoError(err)
|
||||
|
||||
myfs, err := New(info)
|
||||
r.NoError(err)
|
||||
|
||||
suite, err := fstest.NewFileSystem(myfs)
|
||||
r.NoError(err)
|
||||
|
||||
suite.Test(t)
|
||||
}
|
||||
|
|
|
@ -1,34 +1,24 @@
|
|||
package memfs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/markbates/pkger/here"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Open(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
fs, err := New(here.Info{})
|
||||
r.NoError(err)
|
||||
|
||||
_, err = fs.Open("/i.dont.exist")
|
||||
r.Error(err)
|
||||
|
||||
f, err := fs.Create("/i.exist")
|
||||
r.NoError(err)
|
||||
_, err = io.Copy(f, strings.NewReader(radio))
|
||||
r.NoError(err)
|
||||
r.NoError(f.Close())
|
||||
|
||||
f, err = fs.Open("/i.exist")
|
||||
r.NoError(err)
|
||||
b, err := ioutil.ReadAll(f)
|
||||
r.NoError(err)
|
||||
r.NoError(f.Close())
|
||||
r.Equal([]byte(radio), b)
|
||||
}
|
||||
// func Test_Open(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// fs, err := New(here.Info{})
|
||||
// r.NoError(err)
|
||||
//
|
||||
// _, err = fs.Open("/i.dont.exist")
|
||||
// r.Error(err)
|
||||
//
|
||||
// f, err := fs.Create("/i.exist")
|
||||
// r.NoError(err)
|
||||
// _, err = io.Copy(f, strings.NewReader(radio))
|
||||
// r.NoError(err)
|
||||
// r.NoError(f.Close())
|
||||
//
|
||||
// f, err = fs.Open("/i.exist")
|
||||
// r.NoError(err)
|
||||
// b, err := ioutil.ReadAll(f)
|
||||
// r.NoError(err)
|
||||
// r.NoError(f.Close())
|
||||
// r.Equal([]byte(radio), b)
|
||||
// }
|
||||
|
|
253
open_test.go
253
open_test.go
|
@ -1,133 +1,124 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Open_File(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
f, err := Open(".")
|
||||
r.NoError(err)
|
||||
|
||||
ts := httptest.NewServer(http.FileServer(f))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/cmd/pkger/main.go")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(res.Body)
|
||||
r.NoError(err)
|
||||
r.Contains(string(b), "does not compute")
|
||||
|
||||
r.NoError(f.Close())
|
||||
}
|
||||
|
||||
func Test_Open_Dir(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
f, err := Open("/")
|
||||
r.NoError(err)
|
||||
|
||||
ts := httptest.NewServer(http.FileServer(f))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/cmd/pkger")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(res.Body)
|
||||
r.NoError(err)
|
||||
r.Contains(string(b), `<a href="/cmd/pkger/main.go">/cmd/pkger/main.go</a>`)
|
||||
|
||||
r.NoError(f.Close())
|
||||
}
|
||||
|
||||
func Test_Open_File_Memory(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
f, err := Create("/suit/case.txt")
|
||||
r.NoError(err)
|
||||
f.Write([]byte(radio))
|
||||
r.NoError(f.Close())
|
||||
|
||||
r.Equal([]byte(radio), f.data)
|
||||
r.Contains(string(f.data), "I wanna bite the hand that feeds me")
|
||||
|
||||
dir, err := Open("/")
|
||||
r.NoError(err)
|
||||
defer dir.Close()
|
||||
|
||||
ts := httptest.NewServer(http.FileServer(dir))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/suit/case.txt")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), "I wanna bite the hand that feeds me")
|
||||
|
||||
}
|
||||
|
||||
func Test_Open_Dir_StripPrefix(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public"))))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/assets/radio.radio")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), "I wanna bite the hand that feeds me")
|
||||
|
||||
res, err = http.Get(ts.URL + "/assets/")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ = ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), `<a href="radio.radio">radio.radio</a>`)
|
||||
}
|
||||
|
||||
func Test_Open_Dir_Memory_StripPrefix(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
err := MkdirAll("/testdata/public", 0755)
|
||||
r.NoError(err)
|
||||
|
||||
dir, err := Open("/testdata/public")
|
||||
r.NoError(err)
|
||||
defer dir.Close()
|
||||
|
||||
ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir)))
|
||||
defer ts.Close()
|
||||
|
||||
res, err := http.Get(ts.URL + "/assets/radio.radio")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), "I wanna bite the hand that feeds me")
|
||||
|
||||
res, err = http.Get(ts.URL + "/assets/")
|
||||
r.NoError(err)
|
||||
r.Equal(200, res.StatusCode)
|
||||
|
||||
b, _ = ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
r.Contains(string(b), `<a href="/radio.radio">/radio.radio</a>`)
|
||||
r.NotContains(string(b), `/public`)
|
||||
r.NotContains(string(b), `//`)
|
||||
}
|
||||
// func Test_Open_File(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// f, err := Open(".")
|
||||
// r.NoError(err)
|
||||
//
|
||||
// ts := httptest.NewServer(http.FileServer(f))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/cmd/pkger/main.go")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, err := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
// r.Contains(string(b), "does not compute")
|
||||
//
|
||||
// r.NoError(f.Close())
|
||||
// }
|
||||
//
|
||||
// func Test_Open_Dir(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// f, err := Open("/")
|
||||
// r.NoError(err)
|
||||
//
|
||||
// ts := httptest.NewServer(http.FileServer(f))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/cmd/pkger")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, err := ioutil.ReadAll(res.Body)
|
||||
// r.NoError(err)
|
||||
// r.Contains(string(b), `<a href="/cmd/pkger/main.go">/cmd/pkger/main.go</a>`)
|
||||
//
|
||||
// r.NoError(f.Close())
|
||||
// }
|
||||
//
|
||||
// func Test_Open_File_Memory(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// f, err := Create("/suit/case.txt")
|
||||
// r.NoError(err)
|
||||
// f.Write([]byte(radio))
|
||||
// r.NoError(f.Close())
|
||||
//
|
||||
// r.Equal([]byte(radio), f.data)
|
||||
// r.Contains(string(f.data), "I wanna bite the hand that feeds me")
|
||||
//
|
||||
// dir, err := Open("/")
|
||||
// r.NoError(err)
|
||||
// defer dir.Close()
|
||||
//
|
||||
// ts := httptest.NewServer(http.FileServer(dir))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/suit/case.txt")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ := ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), "I wanna bite the hand that feeds me")
|
||||
//
|
||||
// }
|
||||
//
|
||||
// func Test_Open_Dir_StripPrefix(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public"))))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/assets/radio.radio")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ := ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), "I wanna bite the hand that feeds me")
|
||||
//
|
||||
// res, err = http.Get(ts.URL + "/assets/")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ = ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), `<a href="radio.radio">radio.radio</a>`)
|
||||
// }
|
||||
//
|
||||
// func Test_Open_Dir_Memory_StripPrefix(t *testing.T) {
|
||||
// r := require.New(t)
|
||||
//
|
||||
// err := MkdirAll("/testdata/public", 0755)
|
||||
// r.NoError(err)
|
||||
//
|
||||
// dir, err := Open("/testdata/public")
|
||||
// r.NoError(err)
|
||||
// defer dir.Close()
|
||||
//
|
||||
// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir)))
|
||||
// defer ts.Close()
|
||||
//
|
||||
// res, err := http.Get(ts.URL + "/assets/radio.radio")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ := ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), "I wanna bite the hand that feeds me")
|
||||
//
|
||||
// res, err = http.Get(ts.URL + "/assets/")
|
||||
// r.NoError(err)
|
||||
// r.Equal(200, res.StatusCode)
|
||||
//
|
||||
// b, _ = ioutil.ReadAll(res.Body)
|
||||
// // r.NoError(err)
|
||||
// r.Contains(string(b), `<a href="/radio.radio">/radio.radio</a>`)
|
||||
// r.NotContains(string(b), `/public`)
|
||||
// r.NotContains(string(b), `//`)
|
||||
// }
|
||||
|
|
Loading…
Reference in New Issue