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 }