| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file.package zipfs |
| package zipfs |
| |
| import ( |
| "archive/zip" |
| "bytes" |
| "fmt" |
| "io" |
| "io/ioutil" |
| "os" |
| "reflect" |
| "testing" |
| |
| "golang.org/x/tools/godoc/vfs" |
| ) |
| |
| var ( |
| |
| // files to use to build zip used by zipfs in testing; maps path : contents |
| files = map[string]string{"foo": "foo", "bar/baz": "baz", "a/b/c": "c"} |
| |
| // expected info for each entry in a file system described by files |
| tests = []struct { |
| Path string |
| IsDir bool |
| IsRegular bool |
| Name string |
| Contents string |
| Files map[string]bool |
| }{ |
| {"/", true, false, "", "", map[string]bool{"foo": true, "bar": true, "a": true}}, |
| {"//", true, false, "", "", map[string]bool{"foo": true, "bar": true, "a": true}}, |
| {"/foo", false, true, "foo", "foo", nil}, |
| {"/foo/", false, true, "foo", "foo", nil}, |
| {"/foo//", false, true, "foo", "foo", nil}, |
| {"/bar", true, false, "bar", "", map[string]bool{"baz": true}}, |
| {"/bar/", true, false, "bar", "", map[string]bool{"baz": true}}, |
| {"/bar/baz", false, true, "baz", "baz", nil}, |
| {"//bar//baz", false, true, "baz", "baz", nil}, |
| {"/a/b", true, false, "b", "", map[string]bool{"c": true}}, |
| } |
| |
| // to be initialized in setup() |
| fs vfs.FileSystem |
| statFuncs []statFunc |
| ) |
| |
| type statFunc struct { |
| Name string |
| Func func(string) (os.FileInfo, error) |
| } |
| |
| func TestMain(t *testing.M) { |
| if err := setup(); err != nil { |
| fmt.Fprintf(os.Stderr, "Error setting up zipfs testing state: %v.\n", err) |
| os.Exit(1) |
| } |
| os.Exit(t.Run()) |
| } |
| |
| // setups state each of the tests uses |
| func setup() error { |
| // create zipfs |
| b := new(bytes.Buffer) |
| zw := zip.NewWriter(b) |
| for file, contents := range files { |
| w, err := zw.Create(file) |
| if err != nil { |
| return err |
| } |
| _, err = io.WriteString(w, contents) |
| if err != nil { |
| return err |
| } |
| } |
| zw.Close() |
| zr, err := zip.NewReader(bytes.NewReader(b.Bytes()), int64(b.Len())) |
| if err != nil { |
| return err |
| } |
| rc := &zip.ReadCloser{ |
| Reader: *zr, |
| } |
| fs = New(rc, "foo") |
| |
| // pull out different stat functions |
| statFuncs = []statFunc{ |
| {"Stat", fs.Stat}, |
| {"Lstat", fs.Lstat}, |
| } |
| |
| return nil |
| } |
| |
| func TestZipFSReadDir(t *testing.T) { |
| for _, test := range tests { |
| if test.IsDir { |
| infos, err := fs.ReadDir(test.Path) |
| if err != nil { |
| t.Errorf("Failed to read directory %v\n", test.Path) |
| continue |
| } |
| got := make(map[string]bool) |
| for _, info := range infos { |
| got[info.Name()] = true |
| } |
| if want := test.Files; !reflect.DeepEqual(got, want) { |
| t.Errorf("ReadDir %v got %v\nwanted %v\n", test.Path, got, want) |
| } |
| } |
| } |
| } |
| |
| func TestZipFSStatFuncs(t *testing.T) { |
| for _, test := range tests { |
| for _, statFunc := range statFuncs { |
| |
| // test can stat |
| info, err := statFunc.Func(test.Path) |
| if err != nil { |
| t.Errorf("Unexpected error using %v for %v: %v\n", statFunc.Name, test.Path, err) |
| continue |
| } |
| |
| // test info.Name() |
| if got, want := info.Name(), test.Name; got != want { |
| t.Errorf("Using %v for %v info.Name() got %v wanted %v\n", statFunc.Name, test.Path, got, want) |
| } |
| // test info.IsDir() |
| if got, want := info.IsDir(), test.IsDir; got != want { |
| t.Errorf("Using %v for %v info.IsDir() got %v wanted %v\n", statFunc.Name, test.Path, got, want) |
| } |
| // test info.Mode().IsDir() |
| if got, want := info.Mode().IsDir(), test.IsDir; got != want { |
| t.Errorf("Using %v for %v info.Mode().IsDir() got %v wanted %v\n", statFunc.Name, test.Path, got, want) |
| } |
| // test info.Mode().IsRegular() |
| if got, want := info.Mode().IsRegular(), test.IsRegular; got != want { |
| t.Errorf("Using %v for %v info.Mode().IsRegular() got %v wanted %v\n", statFunc.Name, test.Path, got, want) |
| } |
| // test info.Size() |
| if test.IsRegular { |
| if got, want := info.Size(), int64(len(test.Contents)); got != want { |
| t.Errorf("Using %v for %v inf.Size() got %v wanted %v", statFunc.Name, test.Path, got, want) |
| } |
| } |
| } |
| } |
| } |
| |
| func TestZipFSNotExist(t *testing.T) { |
| _, err := fs.Open("/does-not-exist") |
| if err == nil { |
| t.Fatalf("Expected an error.\n") |
| } |
| if !os.IsNotExist(err) { |
| t.Errorf("Expected an error satisfying os.IsNotExist: %v\n", err) |
| } |
| } |
| |
| func TestZipFSOpenSeek(t *testing.T) { |
| for _, test := range tests { |
| if test.IsRegular { |
| |
| // test Open() |
| f, err := fs.Open(test.Path) |
| if err != nil { |
| t.Error(err) |
| return |
| } |
| defer f.Close() |
| |
| // test Seek() multiple times |
| for i := 0; i < 3; i++ { |
| all, err := ioutil.ReadAll(f) |
| if err != nil { |
| t.Error(err) |
| return |
| } |
| if got, want := string(all), test.Contents; got != want { |
| t.Errorf("File contents for %v got %v wanted %v\n", test.Path, got, want) |
| } |
| f.Seek(0, 0) |
| } |
| } |
| } |
| } |
| |
| func TestRootType(t *testing.T) { |
| tests := []struct { |
| path string |
| fsType vfs.RootType |
| }{ |
| {"/src/net/http", vfs.RootTypeGoRoot}, |
| {"/src/badpath", ""}, |
| {"/", vfs.RootTypeGoRoot}, |
| } |
| |
| for _, item := range tests { |
| if fs.RootType(item.path) != item.fsType { |
| t.Errorf("unexpected fsType. Expected- %v, Got- %v", item.fsType, fs.RootType(item.path)) |
| } |
| } |
| } |