github.com/bpfs/defs@v0.0.15/afero/util_test.go (about)

     1  // Copyright ©2015 Steve Francia <spf@spf13.com>
     2  // Portions Copyright ©2015 The Hugo Authors
     3  //
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  //
    17  
    18  package afero
    19  
    20  import (
    21  	"fmt"
    22  	"os"
    23  	"path/filepath"
    24  	"strconv"
    25  	"strings"
    26  	"testing"
    27  	"time"
    28  )
    29  
    30  var testFS = new(MemMapFs)
    31  
    32  func TestDirExists(t *testing.T) {
    33  	type test struct {
    34  		input    string
    35  		expected bool
    36  	}
    37  
    38  	// First create a couple directories so there is something in the filesystem
    39  	// testFS := new(MemMapFs)
    40  	testFS.MkdirAll("/foo/bar", 0o777)
    41  
    42  	data := []test{
    43  		{".", true},
    44  		{"./", true},
    45  		{"..", true},
    46  		{"../", true},
    47  		{"./..", true},
    48  		{"./../", true},
    49  		{"/foo/", true},
    50  		{"/foo", true},
    51  		{"/foo/bar", true},
    52  		{"/foo/bar/", true},
    53  		{"/", true},
    54  		{"/some-really-random-directory-name", false},
    55  		{"/some/really/random/directory/name", false},
    56  		{"./some-really-random-local-directory-name", false},
    57  		{"./some/really/random/local/directory/name", false},
    58  	}
    59  
    60  	for i, d := range data {
    61  		exists, _ := DirExists(testFS, filepath.FromSlash(d.input))
    62  		if d.expected != exists {
    63  			t.Errorf("Test %d %q failed. Expected %t got %t", i, d.input, d.expected, exists)
    64  		}
    65  	}
    66  }
    67  
    68  func TestIsDir(t *testing.T) {
    69  	testFS = new(MemMapFs)
    70  
    71  	type test struct {
    72  		input    string
    73  		expected bool
    74  	}
    75  	data := []test{
    76  		{"./", true},
    77  		{"/", true},
    78  		{"./this-directory-does-not-existi", false},
    79  		{"/this-absolute-directory/does-not-exist", false},
    80  	}
    81  
    82  	for i, d := range data {
    83  
    84  		exists, _ := IsDir(testFS, d.input)
    85  		if d.expected != exists {
    86  			t.Errorf("Test %d failed. Expected %t got %t", i, d.expected, exists)
    87  		}
    88  	}
    89  }
    90  
    91  func TestIsEmpty(t *testing.T) {
    92  	testFS = new(MemMapFs)
    93  
    94  	zeroSizedFile, _ := createZeroSizedFileInTempDir()
    95  	defer deleteFileInTempDir(zeroSizedFile)
    96  	nonZeroSizedFile, _ := createNonZeroSizedFileInTempDir()
    97  	defer deleteFileInTempDir(nonZeroSizedFile)
    98  	emptyDirectory, _ := createEmptyTempDir()
    99  	defer deleteTempDir(emptyDirectory)
   100  	nonEmptyZeroLengthFilesDirectory, _ := createTempDirWithZeroLengthFiles()
   101  	defer deleteTempDir(nonEmptyZeroLengthFilesDirectory)
   102  	nonEmptyNonZeroLengthFilesDirectory, _ := createTempDirWithNonZeroLengthFiles()
   103  	defer deleteTempDir(nonEmptyNonZeroLengthFilesDirectory)
   104  	nonExistentFile := os.TempDir() + "/this-file-does-not-exist.txt"
   105  	nonExistentDir := os.TempDir() + "/this/direcotry/does/not/exist/"
   106  
   107  	fileDoesNotExist := fmt.Errorf("%q path does not exist", nonExistentFile)
   108  	dirDoesNotExist := fmt.Errorf("%q path does not exist", nonExistentDir)
   109  
   110  	type test struct {
   111  		input          string
   112  		expectedResult bool
   113  		expectedErr    error
   114  	}
   115  
   116  	data := []test{
   117  		{zeroSizedFile.Name(), true, nil},
   118  		{nonZeroSizedFile.Name(), false, nil},
   119  		{emptyDirectory, true, nil},
   120  		{nonEmptyZeroLengthFilesDirectory, false, nil},
   121  		{nonEmptyNonZeroLengthFilesDirectory, false, nil},
   122  		{nonExistentFile, false, fileDoesNotExist},
   123  		{nonExistentDir, false, dirDoesNotExist},
   124  	}
   125  	for i, d := range data {
   126  		exists, err := IsEmpty(testFS, d.input)
   127  		if d.expectedResult != exists {
   128  			t.Errorf("Test %d %q failed exists. Expected result %t got %t", i, d.input, d.expectedResult, exists)
   129  		}
   130  		if d.expectedErr != nil {
   131  			if d.expectedErr.Error() != err.Error() {
   132  				t.Errorf("Test %d failed with err. Expected %q(%#v) got %q(%#v)", i, d.expectedErr, d.expectedErr, err, err)
   133  			}
   134  		} else {
   135  			if d.expectedErr != err {
   136  				t.Errorf("Test %d failed. Expected error %q(%#v) got %q(%#v)", i, d.expectedErr, d.expectedErr, err, err)
   137  			}
   138  		}
   139  	}
   140  }
   141  
   142  func TestReaderContains(t *testing.T) {
   143  	for i, this := range []struct {
   144  		v1     string
   145  		v2     [][]byte
   146  		expect bool
   147  	}{
   148  		{"abc", [][]byte{[]byte("a")}, true},
   149  		{"abc", [][]byte{[]byte("b")}, true},
   150  		{"abcdefg", [][]byte{[]byte("efg")}, true},
   151  		{"abc", [][]byte{[]byte("d")}, false},
   152  		{"abc", [][]byte{[]byte("d"), []byte("e")}, false},
   153  		{"abc", [][]byte{[]byte("d"), []byte("a")}, true},
   154  		{"abc", [][]byte{[]byte("b"), []byte("e")}, true},
   155  		{"", nil, false},
   156  		{"", [][]byte{[]byte("a")}, false},
   157  		{"a", [][]byte{[]byte("")}, false},
   158  		{"", [][]byte{[]byte("")}, false},
   159  	} {
   160  		result := readerContainsAny(strings.NewReader(this.v1), this.v2...)
   161  		if result != this.expect {
   162  			t.Errorf("[%d] readerContains: got %t but expected %t", i, result, this.expect)
   163  		}
   164  	}
   165  
   166  	if readerContainsAny(nil, []byte("a")) {
   167  		t.Error("readerContains with nil reader")
   168  	}
   169  
   170  	if readerContainsAny(nil, nil) {
   171  		t.Error("readerContains with nil arguments")
   172  	}
   173  }
   174  
   175  func createZeroSizedFileInTempDir() (File, error) {
   176  	filePrefix := "_path_test_"
   177  	f, e := TempFile(testFS, "", filePrefix) // dir is os.TempDir()
   178  	if e != nil {
   179  		// if there was an error no file was created.
   180  		// => no requirement to delete the file
   181  		return nil, e
   182  	}
   183  	return f, nil
   184  }
   185  
   186  func createNonZeroSizedFileInTempDir() (File, error) {
   187  	f, err := createZeroSizedFileInTempDir()
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  	byteString := []byte("byteString")
   192  	err = WriteFile(testFS, f.Name(), byteString, 0o644)
   193  	if err != nil {
   194  		// delete the file
   195  		deleteFileInTempDir(f)
   196  		return nil, err
   197  	}
   198  	return f, nil
   199  }
   200  
   201  func deleteFileInTempDir(f File) {
   202  	err := testFS.Remove(f.Name())
   203  	if err != nil {
   204  		panic(err)
   205  	}
   206  }
   207  
   208  func createEmptyTempDir() (string, error) {
   209  	dirPrefix := "_dir_prefix_"
   210  	d, e := TempDir(testFS, "", dirPrefix) // will be in os.TempDir()
   211  	if e != nil {
   212  		// no directory to delete - it was never created
   213  		return "", e
   214  	}
   215  	return d, nil
   216  }
   217  
   218  func createTempDirWithZeroLengthFiles() (string, error) {
   219  	d, dirErr := createEmptyTempDir()
   220  	if dirErr != nil {
   221  		return "", dirErr
   222  	}
   223  	filePrefix := "_path_test_"
   224  	_, fileErr := TempFile(testFS, d, filePrefix) // dir is os.TempDir()
   225  	if fileErr != nil {
   226  		// if there was an error no file was created.
   227  		// but we need to remove the directory to clean-up
   228  		deleteTempDir(d)
   229  		return "", fileErr
   230  	}
   231  	// the dir now has one, zero length file in it
   232  	return d, nil
   233  }
   234  
   235  func createTempDirWithNonZeroLengthFiles() (string, error) {
   236  	d, dirErr := createEmptyTempDir()
   237  	if dirErr != nil {
   238  		return "", dirErr
   239  	}
   240  	filePrefix := "_path_test_"
   241  	f, fileErr := TempFile(testFS, d, filePrefix) // dir is os.TempDir()
   242  	if fileErr != nil {
   243  		// if there was an error no file was created.
   244  		// but we need to remove the directory to clean-up
   245  		deleteTempDir(d)
   246  		return "", fileErr
   247  	}
   248  	byteString := []byte("byteString")
   249  	fileErr = WriteFile(testFS, f.Name(), byteString, 0o644)
   250  	if fileErr != nil {
   251  		// delete the file
   252  		deleteFileInTempDir(f)
   253  		// also delete the directory
   254  		deleteTempDir(d)
   255  		return "", fileErr
   256  	}
   257  
   258  	// the dir now has one, zero length file in it
   259  	return d, nil
   260  }
   261  
   262  func TestExists(t *testing.T) {
   263  	zeroSizedFile, _ := createZeroSizedFileInTempDir()
   264  	defer deleteFileInTempDir(zeroSizedFile)
   265  	nonZeroSizedFile, _ := createNonZeroSizedFileInTempDir()
   266  	defer deleteFileInTempDir(nonZeroSizedFile)
   267  	emptyDirectory, _ := createEmptyTempDir()
   268  	defer deleteTempDir(emptyDirectory)
   269  	nonExistentFile := os.TempDir() + "/this-file-does-not-exist.txt"
   270  	nonExistentDir := os.TempDir() + "/this/direcotry/does/not/exist/"
   271  
   272  	type test struct {
   273  		input          string
   274  		expectedResult bool
   275  		expectedErr    error
   276  	}
   277  
   278  	data := []test{
   279  		{zeroSizedFile.Name(), true, nil},
   280  		{nonZeroSizedFile.Name(), true, nil},
   281  		{emptyDirectory, true, nil},
   282  		{nonExistentFile, false, nil},
   283  		{nonExistentDir, false, nil},
   284  	}
   285  	for i, d := range data {
   286  		exists, err := Exists(testFS, d.input)
   287  		if d.expectedResult != exists {
   288  			t.Errorf("Test %d failed. Expected result %t got %t", i, d.expectedResult, exists)
   289  		}
   290  		if d.expectedErr != err {
   291  			t.Errorf("Test %d failed. Expected %q got %q", i, d.expectedErr, err)
   292  		}
   293  	}
   294  }
   295  
   296  func TestSafeWriteToDisk(t *testing.T) {
   297  	emptyFile, _ := createZeroSizedFileInTempDir()
   298  	defer deleteFileInTempDir(emptyFile)
   299  	tmpDir, _ := createEmptyTempDir()
   300  	defer deleteTempDir(tmpDir)
   301  
   302  	randomString := "This is a random string!"
   303  	reader := strings.NewReader(randomString)
   304  
   305  	fileExists := fmt.Errorf("%v already exists", emptyFile.Name())
   306  
   307  	type test struct {
   308  		filename    string
   309  		expectedErr error
   310  	}
   311  
   312  	now := time.Now().Unix()
   313  	nowStr := strconv.FormatInt(now, 10)
   314  	data := []test{
   315  		{emptyFile.Name(), fileExists},
   316  		{tmpDir + "/" + nowStr, nil},
   317  	}
   318  
   319  	for i, d := range data {
   320  		e := SafeWriteReader(testFS, d.filename, reader)
   321  		if d.expectedErr != nil {
   322  			if d.expectedErr.Error() != e.Error() {
   323  				t.Errorf("Test %d failed. Expected error %q but got %q", i, d.expectedErr.Error(), e.Error())
   324  			}
   325  		} else {
   326  			if d.expectedErr != e {
   327  				t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedErr, e)
   328  			}
   329  			contents, _ := ReadFile(testFS, d.filename)
   330  			if randomString != string(contents) {
   331  				t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents))
   332  			}
   333  		}
   334  		reader.Seek(0, 0)
   335  	}
   336  }
   337  
   338  func TestWriteToDisk(t *testing.T) {
   339  	emptyFile, _ := createZeroSizedFileInTempDir()
   340  	defer deleteFileInTempDir(emptyFile)
   341  	tmpDir, _ := createEmptyTempDir()
   342  	defer deleteTempDir(tmpDir)
   343  
   344  	randomString := "This is a random string!"
   345  	reader := strings.NewReader(randomString)
   346  
   347  	type test struct {
   348  		filename    string
   349  		expectedErr error
   350  	}
   351  
   352  	now := time.Now().Unix()
   353  	nowStr := strconv.FormatInt(now, 10)
   354  	data := []test{
   355  		{emptyFile.Name(), nil},
   356  		{tmpDir + "/" + nowStr, nil},
   357  	}
   358  
   359  	for i, d := range data {
   360  		e := WriteReader(testFS, d.filename, reader)
   361  		if d.expectedErr != e {
   362  			t.Errorf("Test %d failed. WriteToDisk Error Expected %q but got %q", i, d.expectedErr, e)
   363  		}
   364  		contents, e := ReadFile(testFS, d.filename)
   365  		if e != nil {
   366  			t.Errorf("Test %d failed. Could not read file %s. Reason: %s\n", i, d.filename, e)
   367  		}
   368  		if randomString != string(contents) {
   369  			t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents))
   370  		}
   371  		reader.Seek(0, 0)
   372  	}
   373  }
   374  
   375  func TestGetTempDir(t *testing.T) {
   376  	dir := os.TempDir()
   377  	if FilePathSeparator != dir[len(dir)-1:] {
   378  		dir = dir + FilePathSeparator
   379  	}
   380  	testDir := "hugoTestFolder" + FilePathSeparator
   381  	tests := []struct {
   382  		input    string
   383  		expected string
   384  	}{
   385  		{"", dir},
   386  		{testDir + "  Foo bar  ", dir + testDir + "  Foo bar  " + FilePathSeparator},
   387  		{testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + FilePathSeparator},
   388  		{testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoo%bAR" + FilePathSeparator},
   389  		{testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + FilePathSeparator},
   390  		{testDir + "трям/трям", dir + testDir + "трям/трям" + FilePathSeparator},
   391  		{testDir + "은행", dir + testDir + "은행" + FilePathSeparator},
   392  		{testDir + "Банковский кассир", dir + testDir + "Банковский кассир" + FilePathSeparator},
   393  	}
   394  
   395  	for _, test := range tests {
   396  		output := GetTempDir(new(MemMapFs), test.input)
   397  		if output != test.expected {
   398  			t.Errorf("Expected %#v, got %#v\n", test.expected, output)
   399  		}
   400  	}
   401  }
   402  
   403  // This function is very dangerous. Don't use it.
   404  func deleteTempDir(d string) {
   405  	err := os.RemoveAll(d)
   406  	if err != nil {
   407  		panic(err)
   408  	}
   409  }
   410  
   411  func TestFullBaseFsPath(t *testing.T) {
   412  	type dirSpec struct {
   413  		Dir1, Dir2, Dir3 string
   414  	}
   415  	dirSpecs := []dirSpec{
   416  		{Dir1: "/", Dir2: "/", Dir3: "/"},
   417  		{Dir1: "/", Dir2: "/path2", Dir3: "/"},
   418  		{Dir1: "/path1/dir", Dir2: "/path2/dir/", Dir3: "/path3/dir"},
   419  		{Dir1: "C:/path1", Dir2: "path2/dir", Dir3: "/path3/dir/"},
   420  	}
   421  
   422  	for _, ds := range dirSpecs {
   423  		memFs := NewMemMapFs()
   424  		level1Fs := NewBasePathFs(memFs, ds.Dir1)
   425  		level2Fs := NewBasePathFs(level1Fs, ds.Dir2)
   426  		level3Fs := NewBasePathFs(level2Fs, ds.Dir3)
   427  
   428  		type spec struct {
   429  			BaseFs       Fs
   430  			FileName     string
   431  			ExpectedPath string
   432  		}
   433  		specs := []spec{
   434  			{BaseFs: level3Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, ds.Dir3, "f.txt")},
   435  			{BaseFs: level3Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, ds.Dir3, "")},
   436  			{BaseFs: level2Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, "f.txt")},
   437  			{BaseFs: level2Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, "")},
   438  			{BaseFs: level1Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, "f.txt")},
   439  			{BaseFs: level1Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, "")},
   440  		}
   441  
   442  		for _, s := range specs {
   443  			if actualPath := FullBaseFsPath(s.BaseFs.(*BasePathFs), s.FileName); actualPath != s.ExpectedPath {
   444  				t.Errorf("Expected \n%s got \n%s", s.ExpectedPath, actualPath)
   445  			}
   446  		}
   447  	}
   448  }