github.com/v2fly/tools@v0.100.0/godoc/vfs/zipfs/zipfs_test.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.package zipfs
     4  package zipfs
     5  
     6  import (
     7  	"archive/zip"
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"os"
    13  	"reflect"
    14  	"testing"
    15  
    16  	"github.com/v2fly/tools/godoc/vfs"
    17  )
    18  
    19  var (
    20  
    21  	// files to use to build zip used by zipfs in testing; maps path : contents
    22  	files = map[string]string{"foo": "foo", "bar/baz": "baz", "a/b/c": "c"}
    23  
    24  	// expected info for each entry in a file system described by files
    25  	tests = []struct {
    26  		Path      string
    27  		IsDir     bool
    28  		IsRegular bool
    29  		Name      string
    30  		Contents  string
    31  		Files     map[string]bool
    32  	}{
    33  		{"/", true, false, "", "", map[string]bool{"foo": true, "bar": true, "a": true}},
    34  		{"//", true, false, "", "", map[string]bool{"foo": true, "bar": true, "a": true}},
    35  		{"/foo", false, true, "foo", "foo", nil},
    36  		{"/foo/", false, true, "foo", "foo", nil},
    37  		{"/foo//", false, true, "foo", "foo", nil},
    38  		{"/bar", true, false, "bar", "", map[string]bool{"baz": true}},
    39  		{"/bar/", true, false, "bar", "", map[string]bool{"baz": true}},
    40  		{"/bar/baz", false, true, "baz", "baz", nil},
    41  		{"//bar//baz", false, true, "baz", "baz", nil},
    42  		{"/a/b", true, false, "b", "", map[string]bool{"c": true}},
    43  	}
    44  
    45  	// to be initialized in setup()
    46  	fs        vfs.FileSystem
    47  	statFuncs []statFunc
    48  )
    49  
    50  type statFunc struct {
    51  	Name string
    52  	Func func(string) (os.FileInfo, error)
    53  }
    54  
    55  func TestMain(t *testing.M) {
    56  	if err := setup(); err != nil {
    57  		fmt.Fprintf(os.Stderr, "Error setting up zipfs testing state: %v.\n", err)
    58  		os.Exit(1)
    59  	}
    60  	os.Exit(t.Run())
    61  }
    62  
    63  // setups state each of the tests uses
    64  func setup() error {
    65  	// create zipfs
    66  	b := new(bytes.Buffer)
    67  	zw := zip.NewWriter(b)
    68  	for file, contents := range files {
    69  		w, err := zw.Create(file)
    70  		if err != nil {
    71  			return err
    72  		}
    73  		_, err = io.WriteString(w, contents)
    74  		if err != nil {
    75  			return err
    76  		}
    77  	}
    78  	zw.Close()
    79  	zr, err := zip.NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
    80  	if err != nil {
    81  		return err
    82  	}
    83  	rc := &zip.ReadCloser{
    84  		Reader: *zr,
    85  	}
    86  	fs = New(rc, "foo")
    87  
    88  	// pull out different stat functions
    89  	statFuncs = []statFunc{
    90  		{"Stat", fs.Stat},
    91  		{"Lstat", fs.Lstat},
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func TestZipFSReadDir(t *testing.T) {
    98  	for _, test := range tests {
    99  		if test.IsDir {
   100  			infos, err := fs.ReadDir(test.Path)
   101  			if err != nil {
   102  				t.Errorf("Failed to read directory %v\n", test.Path)
   103  				continue
   104  			}
   105  			got := make(map[string]bool)
   106  			for _, info := range infos {
   107  				got[info.Name()] = true
   108  			}
   109  			if want := test.Files; !reflect.DeepEqual(got, want) {
   110  				t.Errorf("ReadDir %v got %v\nwanted %v\n", test.Path, got, want)
   111  			}
   112  		}
   113  	}
   114  }
   115  
   116  func TestZipFSStatFuncs(t *testing.T) {
   117  	for _, test := range tests {
   118  		for _, statFunc := range statFuncs {
   119  
   120  			// test can stat
   121  			info, err := statFunc.Func(test.Path)
   122  			if err != nil {
   123  				t.Errorf("Unexpected error using %v for %v: %v\n", statFunc.Name, test.Path, err)
   124  				continue
   125  			}
   126  
   127  			// test info.Name()
   128  			if got, want := info.Name(), test.Name; got != want {
   129  				t.Errorf("Using %v for %v info.Name() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
   130  			}
   131  			// test info.IsDir()
   132  			if got, want := info.IsDir(), test.IsDir; got != want {
   133  				t.Errorf("Using %v for %v info.IsDir() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
   134  			}
   135  			// test info.Mode().IsDir()
   136  			if got, want := info.Mode().IsDir(), test.IsDir; got != want {
   137  				t.Errorf("Using %v for %v info.Mode().IsDir() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
   138  			}
   139  			// test info.Mode().IsRegular()
   140  			if got, want := info.Mode().IsRegular(), test.IsRegular; got != want {
   141  				t.Errorf("Using %v for %v info.Mode().IsRegular() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
   142  			}
   143  			// test info.Size()
   144  			if test.IsRegular {
   145  				if got, want := info.Size(), int64(len(test.Contents)); got != want {
   146  					t.Errorf("Using %v for %v inf.Size() got %v wanted %v", statFunc.Name, test.Path, got, want)
   147  				}
   148  			}
   149  		}
   150  	}
   151  }
   152  
   153  func TestZipFSNotExist(t *testing.T) {
   154  	_, err := fs.Open("/does-not-exist")
   155  	if err == nil {
   156  		t.Fatalf("Expected an error.\n")
   157  	}
   158  	if !os.IsNotExist(err) {
   159  		t.Errorf("Expected an error satisfying os.IsNotExist: %v\n", err)
   160  	}
   161  }
   162  
   163  func TestZipFSOpenSeek(t *testing.T) {
   164  	for _, test := range tests {
   165  		if test.IsRegular {
   166  
   167  			// test Open()
   168  			f, err := fs.Open(test.Path)
   169  			if err != nil {
   170  				t.Error(err)
   171  				return
   172  			}
   173  			defer f.Close()
   174  
   175  			// test Seek() multiple times
   176  			for i := 0; i < 3; i++ {
   177  				all, err := ioutil.ReadAll(f)
   178  				if err != nil {
   179  					t.Error(err)
   180  					return
   181  				}
   182  				if got, want := string(all), test.Contents; got != want {
   183  					t.Errorf("File contents for %v got %v wanted %v\n", test.Path, got, want)
   184  				}
   185  				f.Seek(0, 0)
   186  			}
   187  		}
   188  	}
   189  }
   190  
   191  func TestRootType(t *testing.T) {
   192  	tests := []struct {
   193  		path   string
   194  		fsType vfs.RootType
   195  	}{
   196  		{"/src/net/http", vfs.RootTypeGoRoot},
   197  		{"/src/badpath", ""},
   198  		{"/", vfs.RootTypeGoRoot},
   199  	}
   200  
   201  	for _, item := range tests {
   202  		if fs.RootType(item.path) != item.fsType {
   203  			t.Errorf("unexpected fsType. Expected- %v, Got- %v", item.fsType, fs.RootType(item.path))
   204  		}
   205  	}
   206  }