github.com/IBM/fsgo@v0.0.0-20220920202152-e16fd2119d49/util_test.go (about)

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