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 }