this stolen feeling!

This commit is contained in:
Mark Bates 2019-08-31 22:45:22 -04:00
parent 91ee10f16b
commit 704b38d3ea
18 changed files with 672 additions and 490 deletions

View File

@ -8,13 +8,31 @@ import (
) )
type FileSystem interface { type FileSystem interface {
Create(name string) (File, error) Parse(p string) (Path, error)
Current() (here.Info, error) Current() (here.Info, error)
Info(p string) (here.Info, error) Info(p string) (here.Info, error)
MkdirAll(p string, perm os.FileMode) error
Open(name string) (File, 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.
Parse(p string) (Path, error)
ReadFile(s string) ([]byte, error) 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) 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 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
} }

View File

@ -1,37 +1,12 @@
package fstest package fstest
import ( import (
"bytes"
"io"
"github.com/markbates/pkger/fs" "github.com/markbates/pkger/fs"
) )
type TestFile struct { type TestFile struct {
Name string Name string
Data []byte Path fs.Path
}
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()
} }
type TestFiles map[string]TestFile 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
}

45
fs/fstest/fstest.go Normal file
View File

@ -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",
}

124
fs/fstest/suite.go Normal file
View File

@ -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")
}

View File

@ -69,7 +69,6 @@ func (f *FS) MkdirAll(p string, perm os.FileMode) error {
if err != nil { if err != nil {
return err return err
} }
fmt.Println(">>>TODO fs/hdfs/hdfs.go:73: pp ", p)
return os.MkdirAll(p, perm) 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) { func (f *FS) locate(p string) (string, error) {
return f.current.FilePath(p), nil 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)
}

20
fs/hdfs/hdfs_test.go Normal file
View File

@ -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)
}

View File

View File

View File

View File

@ -23,7 +23,7 @@ func (fx *FS) Create(name string) (fs.File, error) {
info: &fs.FileInfo{ info: &fs.FileInfo{
Details: fs.Details{ Details: fs.Details{
Name: pt.Name, Name: pt.Name,
Mode: 0666, Mode: 0644,
ModTime: fs.ModTime(time.Now()), ModTime: fs.ModTime(time.Now()),
}, },
}, },

View File

@ -1,90 +1,80 @@
package memfs package memfs
import ( // func Test_Create(t *testing.T) {
"io" // r := require.New(t)
"os" //
"strings" // fs, err := New(here.Info{})
"testing" // f, err := fs.Create("/hello.txt")
// r.NoError(err)
"github.com/markbates/pkger/here" // r.NotNil(f)
"github.com/stretchr/testify/require" //
) // fi, err := f.Stat()
// r.NoError(err)
func Test_Create(t *testing.T) { //
r := require.New(t) // r.Equal("/hello.txt", fi.Name())
// r.Equal(os.FileMode(0666), fi.Mode())
fs, err := New(here.Info{}) // r.NotZero(fi.ModTime())
f, err := fs.Create("/hello.txt") // }
r.NoError(err) //
r.NotNil(f) // func Test_Create_Write(t *testing.T) {
// r := require.New(t)
fi, err := f.Stat() //
r.NoError(err) // fs, err := New(here.Info{})
// f, err := fs.Create("/hello.txt")
r.Equal("/hello.txt", fi.Name()) // r.NoError(err)
r.Equal(os.FileMode(0666), fi.Mode()) // r.NotNil(f)
r.NotZero(fi.ModTime()) //
} // fi, err := f.Stat()
// r.NoError(err)
func Test_Create_Write(t *testing.T) { // r.Zero(fi.Size())
r := require.New(t) //
// r.Equal("/hello.txt", fi.Name())
fs, err := New(here.Info{}) //
f, err := fs.Create("/hello.txt") // mt := fi.ModTime()
r.NoError(err) // r.NotZero(mt)
r.NotNil(f) //
// sz, err := io.Copy(f, strings.NewReader(radio))
fi, err := f.Stat() // r.NoError(err)
r.NoError(err) // r.Equal(int64(1381), sz)
r.Zero(fi.Size()) //
// r.NoError(f.Close())
r.Equal("/hello.txt", fi.Name()) // r.Equal(int64(1381), fi.Size())
// r.NotZero(fi.ModTime())
mt := fi.ModTime() // r.NotEqual(mt, fi.ModTime())
r.NotZero(mt) // }
//
sz, err := io.Copy(f, strings.NewReader(radio)) // const radio = `I was tuning in the shine on the late night dial
r.NoError(err) // Doing anything my radio advised
r.Equal(int64(1381), sz) // With every one of those late night stations
// Playing songs bringing tears to my eyes
r.NoError(f.Close()) // I was seriously thinking about hiding the receiver
r.Equal(int64(1381), fi.Size()) // When the switch broke 'cause it's old
r.NotZero(fi.ModTime()) // They're saying things that I can hardly believe
r.NotEqual(mt, fi.ModTime()) // They really think we're getting out of control
} // Radio is a sound salvation
// Radio is cleaning up the nation
const radio = `I was tuning in the shine on the late night dial // They say you better listen to the voice of reason
Doing anything my radio advised // But they don't give you any choice 'cause they think that it's treason
With every one of those late night stations // So you had better do as you are told
Playing songs bringing tears to my eyes // You better listen to the radio
I was seriously thinking about hiding the receiver // I wanna bite the hand that feeds me
When the switch broke 'cause it's old // I wanna bite that hand so badly
They're saying things that I can hardly believe // I want to make them wish they'd never seen me
They really think we're getting out of control // Some of my friends sit around every evening
Radio is a sound salvation // And they worry about the times ahead
Radio is cleaning up the nation // But everybody else is overwhelmed by indifference
They say you better listen to the voice of reason // And the promise of an early bed
But they don't give you any choice 'cause they think that it's treason // You either shut up or get cut up; they don't wanna hear about it
So you had better do as you are told // It's only inches on the reel-to-reel
You better listen to the radio // And the radio is in the hands of such a lot of fools
I wanna bite the hand that feeds me // Tryin' to anesthetize the way that you feel
I wanna bite that hand so badly // Radio is a sound salvation
I want to make them wish they'd never seen me // Radio is cleaning up the nation
Some of my friends sit around every evening // They say you better listen to the voice of reason
And they worry about the times ahead // But they don't give you any choice 'cause they think that it's treason
But everybody else is overwhelmed by indifference // So you had better do as you are told
And the promise of an early bed // You better listen to the radio
You either shut up or get cut up; they don't wanna hear about it // Wonderful radio
It's only inches on the reel-to-reel // Marvelous radio
And the radio is in the hands of such a lot of fools // Wonderful radio
Tryin' to anesthetize the way that you feel // Radio, radio`
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`

View File

@ -1,70 +1,58 @@
package memfs package memfs
import ( // func Test_File_Read_Memory(t *testing.T) {
"bytes" // r := require.New(t)
"io" //
"io/ioutil" // fs, err := New(here.Info{})
"strings" // r.NoError(err)
"testing" //
"time" // f, err := fs.Create("/file_test.go")
// r.NoError(err)
"github.com/markbates/pkger/here" // _, err = io.Copy(f, bytes.NewReader([]byte("hi!")))
"github.com/stretchr/testify/require" // r.NoError(err)
) // r.NoError(f.Close())
//
func Test_File_Read_Memory(t *testing.T) { // f, err = fs.Open("/file_test.go")
r := require.New(t) // r.NoError(err)
// fi, err := f.Stat()
fs, err := New(here.Info{}) // r.NoError(err)
r.NoError(err) // r.Equal("/file_test.go", fi.Name())
//
f, err := fs.Create("/file_test.go") // b, err := ioutil.ReadAll(f)
r.NoError(err) // r.NoError(err)
_, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) // r.Equal(string(b), "hi!")
r.NoError(err) // }
r.NoError(f.Close()) //
// func Test_File_Write(t *testing.T) {
f, err = fs.Open("/file_test.go") // r := require.New(t)
r.NoError(err) //
fi, err := f.Stat() // fs, err := New(here.Info{})
r.NoError(err) // r.NoError(err)
r.Equal("/file_test.go", fi.Name()) //
// f, err := fs.Create("/hello.txt")
b, err := ioutil.ReadAll(f) // r.NoError(err)
r.NoError(err) // r.NotNil(f)
r.Equal(string(b), "hi!") //
} // fi, err := f.Stat()
// r.NoError(err)
func Test_File_Write(t *testing.T) { // r.Zero(fi.Size())
r := require.New(t) //
// r.Equal("/hello.txt", fi.Name())
fs, err := New(here.Info{}) //
r.NoError(err) // mt := fi.ModTime()
// r.NotZero(mt)
f, err := fs.Create("/hello.txt") //
r.NoError(err) // sz, err := io.Copy(f, strings.NewReader(radio))
r.NotNil(f) // r.NoError(err)
// r.Equal(int64(1381), sz)
fi, err := f.Stat() //
r.NoError(err) // // because windows can't handle the time precisely
r.Zero(fi.Size()) // // enough, we have to *force* just a smidge of time
// // to ensure the two ModTime's are different.
r.Equal("/hello.txt", fi.Name()) // // i know, i hate it too.
// time.Sleep(time.Millisecond)
mt := fi.ModTime() // r.NoError(f.Close())
r.NotZero(mt) // r.Equal(int64(1381), fi.Size())
// r.NotZero(fi.ModTime())
sz, err := io.Copy(f, strings.NewReader(radio)) // r.NotEqual(mt, fi.ModTime())
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())
}

View File

@ -1,84 +1,75 @@
package memfs package memfs
import ( // func Test_HTTP_Dir(t *testing.T) {
"io/ioutil" // r := require.New(t)
"net/http" //
"net/http/httptest" // fs := NewFS()
"testing" //
// r.NoError(Folder.Create(fs))
"github.com/stretchr/testify/require" //
) // dir, err := fs.Open("/")
// r.NoError(err)
func Test_HTTP_Dir(t *testing.T) { // ts := httptest.NewServer(http.FileServer(dir))
r := require.New(t) // defer ts.Close()
//
fs := NewFS() // res, err := http.Get(ts.URL + "/")
// r.NoError(err)
r.NoError(Folder.Create(fs)) // r.Equal(200, res.StatusCode)
//
dir, err := fs.Open("/") // b, err := ioutil.ReadAll(res.Body)
r.NoError(err) // r.NoError(err)
ts := httptest.NewServer(http.FileServer(dir)) // r.Contains(string(b), `<a href="/public/images/mark.png">/public/images/mark.png</a>`)
defer ts.Close() // }
//
res, err := http.Get(ts.URL + "/") // func Test_HTTP_File_Memory(t *testing.T) {
r.NoError(err) // r := require.New(t)
r.Equal(200, res.StatusCode) //
// fs := NewFS()
b, err := ioutil.ReadAll(res.Body) // r.NoError(Folder.Create(fs))
r.NoError(err) //
r.Contains(string(b), `<a href="/public/images/mark.png">/public/images/mark.png</a>`) // dir, err := fs.Open("/")
} // r.NoError(err)
// ts := httptest.NewServer(http.FileServer(dir))
func Test_HTTP_File_Memory(t *testing.T) { // defer ts.Close()
r := require.New(t) //
// res, err := http.Get(ts.URL + "/public/images/mark.png")
fs := NewFS() // r.NoError(err)
r.NoError(Folder.Create(fs)) // r.Equal(200, res.StatusCode)
//
dir, err := fs.Open("/") // b, err := ioutil.ReadAll(res.Body)
r.NoError(err) // r.NoError(err)
ts := httptest.NewServer(http.FileServer(dir)) // r.Contains(string(b), `!/public/images/mark.png`)
defer ts.Close() // }
//
res, err := http.Get(ts.URL + "/public/images/mark.png") // func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) {
r.NoError(err) // r := require.New(t)
r.Equal(200, res.StatusCode) //
// fs := NewFS()
b, err := ioutil.ReadAll(res.Body) // r.NoError(Folder.Create(fs))
r.NoError(err) //
r.Contains(string(b), `!/public/images/mark.png`) // dir, err := fs.Open("/public")
} // r.NoError(err)
// defer dir.Close()
func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { //
r := require.New(t) // ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir)))
// defer ts.Close()
fs := NewFS() //
r.NoError(Folder.Create(fs)) // res, err := http.Get(ts.URL + "/assets/images/mark.png")
// r.NoError(err)
dir, err := fs.Open("/public") // r.Equal(200, res.StatusCode)
r.NoError(err) //
defer dir.Close() // b, _ := ioutil.ReadAll(res.Body)
// // r.NoError(err)
ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) // r.Contains(string(b), "!/public/images/mark.png")
defer ts.Close() //
// res, err = http.Get(ts.URL + "/assets/images/")
res, err := http.Get(ts.URL + "/assets/images/mark.png") // r.NoError(err)
r.NoError(err) // r.Equal(200, res.StatusCode)
r.Equal(200, res.StatusCode) //
// b, _ = ioutil.ReadAll(res.Body)
b, _ := ioutil.ReadAll(res.Body) // // r.NoError(err)
// r.NoError(err) // r.Contains(string(b), `<a href="/mark.png">/mark.png</a>`)
r.Contains(string(b), "!/public/images/mark.png") // r.NotContains(string(b), `/public`)
// r.NotContains(string(b), `/images`)
res, err = http.Get(ts.URL + "/assets/images/") // r.NotContains(string(b), `/go.mod`)
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`)
}

View File

@ -1,43 +1,33 @@
package memfs package memfs
import ( // func Test_File_JSON(t *testing.T) {
"encoding/json" // r := require.New(t)
"io" //
"strings" // fs, err := New(here.Info{})
"testing" // r.NoError(err)
//
"github.com/markbates/pkger/here" // f, err := fs.Create("/radio.radio")
"github.com/stretchr/testify/require" // r.NoError(err)
) // _, err = io.Copy(f, strings.NewReader(radio))
// r.NoError(err)
func Test_File_JSON(t *testing.T) { // r.NoError(f.Close())
r := require.New(t) //
// f, err = fs.Open("/radio.radio")
fs, err := New(here.Info{}) // r.NoError(err)
r.NoError(err) // bi, err := f.Stat()
// r.NoError(err)
f, err := fs.Create("/radio.radio") //
r.NoError(err) // mj, err := json.Marshal(f)
_, err = io.Copy(f, strings.NewReader(radio)) // r.NoError(err)
r.NoError(err) //
r.NoError(f.Close()) // f2 := &File{}
//
f, err = fs.Open("/radio.radio") // r.NoError(json.Unmarshal(mj, f2))
r.NoError(err) //
bi, err := f.Stat() // ai, err := f2.Stat()
r.NoError(err) // r.NoError(err)
//
mj, err := json.Marshal(f) // r.Equal(bi.Size(), ai.Size())
r.NoError(err) //
// r.Equal(radio, string(f2.data))
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))
}

View File

@ -1,7 +1,10 @@
package memfs package memfs
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os"
"strings"
"github.com/markbates/pkger/fs" "github.com/markbates/pkger/fs"
"github.com/markbates/pkger/here" "github.com/markbates/pkger/here"
@ -56,3 +59,47 @@ func (fx *FS) ReadFile(s string) ([]byte, error) {
defer f.Close() defer f.Close()
return ioutil.ReadAll(f) 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
}

View File

@ -1,26 +1,24 @@
package memfs package memfs
import ( import (
"log" "testing"
"github.com/markbates/pkger/fs/fstest" "github.com/markbates/pkger/fs/fstest"
"github.com/markbates/pkger/here" "github.com/markbates/pkger/here"
"github.com/stretchr/testify/require"
) )
func NewFS() *FS { func Test_FS(t *testing.T) {
fs, err := New(here.Info{}) r := require.New(t)
if err != nil {
log.Fatal(err)
}
return fs
}
var Folder = fstest.TestFiles{ info, err := here.Current()
"/main.go": {Data: []byte("!/main.go")}, r.NoError(err)
"/go.mod": {Data: []byte("!/go.mod")},
"/go.sum": {Data: []byte("!/go.sum")}, myfs, err := New(info)
"/public/index.html": {Data: []byte("!/public/index.html")}, r.NoError(err)
"/public/images/mark.png": {Data: []byte("!/public/images/mark.png")},
"/templates/a.txt": {Data: []byte("!/templates/a.txt")}, suite, err := fstest.NewFileSystem(myfs)
"/templates/b/b.txt": {Data: []byte("!/templates/b/b.txt")}, r.NoError(err)
suite.Test(t)
} }

View File

@ -1,34 +1,24 @@
package memfs package memfs
import ( // func Test_Open(t *testing.T) {
"io" // r := require.New(t)
"io/ioutil" //
"strings" // fs, err := New(here.Info{})
"testing" // r.NoError(err)
//
"github.com/markbates/pkger/here" // _, err = fs.Open("/i.dont.exist")
"github.com/stretchr/testify/require" // r.Error(err)
) //
// f, err := fs.Create("/i.exist")
func Test_Open(t *testing.T) { // r.NoError(err)
r := require.New(t) // _, err = io.Copy(f, strings.NewReader(radio))
// r.NoError(err)
fs, err := New(here.Info{}) // r.NoError(f.Close())
r.NoError(err) //
// f, err = fs.Open("/i.exist")
_, err = fs.Open("/i.dont.exist") // r.NoError(err)
r.Error(err) // b, err := ioutil.ReadAll(f)
// r.NoError(err)
f, err := fs.Create("/i.exist") // r.NoError(f.Close())
r.NoError(err) // r.Equal([]byte(radio), b)
_, 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)
}

View File

@ -1,133 +1,124 @@
package pkger package pkger
import ( // func Test_Open_File(t *testing.T) {
"io/ioutil" // r := require.New(t)
"net/http" //
"net/http/httptest" // f, err := Open(".")
"testing" // r.NoError(err)
//
"github.com/stretchr/testify/require" // ts := httptest.NewServer(http.FileServer(f))
) // defer ts.Close()
//
func Test_Open_File(t *testing.T) { // res, err := http.Get(ts.URL + "/cmd/pkger/main.go")
r := require.New(t) // r.NoError(err)
// r.Equal(200, res.StatusCode)
f, err := Open(".") //
r.NoError(err) // b, err := ioutil.ReadAll(res.Body)
// r.NoError(err)
ts := httptest.NewServer(http.FileServer(f)) // r.Contains(string(b), "does not compute")
defer ts.Close() //
// r.NoError(f.Close())
res, err := http.Get(ts.URL + "/cmd/pkger/main.go") // }
r.NoError(err) //
r.Equal(200, res.StatusCode) // func Test_Open_Dir(t *testing.T) {
// r := require.New(t)
b, err := ioutil.ReadAll(res.Body) //
r.NoError(err) // f, err := Open("/")
r.Contains(string(b), "does not compute") // r.NoError(err)
//
r.NoError(f.Close()) // ts := httptest.NewServer(http.FileServer(f))
} // defer ts.Close()
//
func Test_Open_Dir(t *testing.T) { // res, err := http.Get(ts.URL + "/cmd/pkger")
r := require.New(t) // r.NoError(err)
// r.Equal(200, res.StatusCode)
f, err := Open("/") //
r.NoError(err) // b, err := ioutil.ReadAll(res.Body)
// r.NoError(err)
ts := httptest.NewServer(http.FileServer(f)) // r.Contains(string(b), `<a href="/cmd/pkger/main.go">/cmd/pkger/main.go</a>`)
defer ts.Close() //
// r.NoError(f.Close())
res, err := http.Get(ts.URL + "/cmd/pkger") // }
r.NoError(err) //
r.Equal(200, res.StatusCode) // func Test_Open_File_Memory(t *testing.T) {
// r := require.New(t)
b, err := ioutil.ReadAll(res.Body) //
r.NoError(err) // f, err := Create("/suit/case.txt")
r.Contains(string(b), `<a href="/cmd/pkger/main.go">/cmd/pkger/main.go</a>`) // r.NoError(err)
// f.Write([]byte(radio))
r.NoError(f.Close()) // r.NoError(f.Close())
} //
// r.Equal([]byte(radio), f.data)
func Test_Open_File_Memory(t *testing.T) { // r.Contains(string(f.data), "I wanna bite the hand that feeds me")
r := require.New(t) //
// dir, err := Open("/")
f, err := Create("/suit/case.txt") // r.NoError(err)
r.NoError(err) // defer dir.Close()
f.Write([]byte(radio)) //
r.NoError(f.Close()) // ts := httptest.NewServer(http.FileServer(dir))
// defer ts.Close()
r.Equal([]byte(radio), f.data) //
r.Contains(string(f.data), "I wanna bite the hand that feeds me") // res, err := http.Get(ts.URL + "/suit/case.txt")
// r.NoError(err)
dir, err := Open("/") // r.Equal(200, res.StatusCode)
r.NoError(err) //
defer dir.Close() // b, _ := ioutil.ReadAll(res.Body)
// // r.NoError(err)
ts := httptest.NewServer(http.FileServer(dir)) // r.Contains(string(b), "I wanna bite the hand that feeds me")
defer ts.Close() //
// }
res, err := http.Get(ts.URL + "/suit/case.txt") //
r.NoError(err) // func Test_Open_Dir_StripPrefix(t *testing.T) {
r.Equal(200, res.StatusCode) // r := require.New(t)
//
b, _ := ioutil.ReadAll(res.Body) // ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public"))))
// r.NoError(err) // defer ts.Close()
r.Contains(string(b), "I wanna bite the hand that feeds me") //
// res, err := http.Get(ts.URL + "/assets/radio.radio")
} // r.NoError(err)
// r.Equal(200, res.StatusCode)
func Test_Open_Dir_StripPrefix(t *testing.T) { //
r := require.New(t) // b, _ := ioutil.ReadAll(res.Body)
// // r.NoError(err)
ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public")))) // r.Contains(string(b), "I wanna bite the hand that feeds me")
defer ts.Close() //
// res, err = http.Get(ts.URL + "/assets/")
res, err := http.Get(ts.URL + "/assets/radio.radio") // r.NoError(err)
r.NoError(err) // r.Equal(200, res.StatusCode)
r.Equal(200, res.StatusCode) //
// b, _ = ioutil.ReadAll(res.Body)
b, _ := ioutil.ReadAll(res.Body) // // r.NoError(err)
// r.NoError(err) // r.Contains(string(b), `<a href="radio.radio">radio.radio</a>`)
r.Contains(string(b), "I wanna bite the hand that feeds me") // }
//
res, err = http.Get(ts.URL + "/assets/") // func Test_Open_Dir_Memory_StripPrefix(t *testing.T) {
r.NoError(err) // r := require.New(t)
r.Equal(200, res.StatusCode) //
// err := MkdirAll("/testdata/public", 0755)
b, _ = ioutil.ReadAll(res.Body) // r.NoError(err)
// r.NoError(err) //
r.Contains(string(b), `<a href="radio.radio">radio.radio</a>`) // dir, err := Open("/testdata/public")
} // r.NoError(err)
// defer dir.Close()
func Test_Open_Dir_Memory_StripPrefix(t *testing.T) { //
r := require.New(t) // ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir)))
// defer ts.Close()
err := MkdirAll("/testdata/public", 0755) //
r.NoError(err) // res, err := http.Get(ts.URL + "/assets/radio.radio")
// r.NoError(err)
dir, err := Open("/testdata/public") // r.Equal(200, res.StatusCode)
r.NoError(err) //
defer dir.Close() // b, _ := ioutil.ReadAll(res.Body)
// // r.NoError(err)
ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) // r.Contains(string(b), "I wanna bite the hand that feeds me")
defer ts.Close() //
// res, err = http.Get(ts.URL + "/assets/")
res, err := http.Get(ts.URL + "/assets/radio.radio") // r.NoError(err)
r.NoError(err) // r.Equal(200, res.StatusCode)
r.Equal(200, res.StatusCode) //
// b, _ = ioutil.ReadAll(res.Body)
b, _ := ioutil.ReadAll(res.Body) // // r.NoError(err)
// r.NoError(err) // r.Contains(string(b), `<a href="/radio.radio">/radio.radio</a>`)
r.Contains(string(b), "I wanna bite the hand that feeds me") // r.NotContains(string(b), `/public`)
// r.NotContains(string(b), `//`)
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), `//`)
}