github.com/xtrafrancyz/afero@v1.1.1/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", 0777) 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 result := readerContainsAny(strings.NewReader(this.v1), this.v2...) 160 if result != this.expect { 161 t.Errorf("[%d] readerContains: got %t but expected %t", i, result, this.expect) 162 } 163 } 164 165 if readerContainsAny(nil, []byte("a")) { 166 t.Error("readerContains with nil reader") 167 } 168 169 if readerContainsAny(nil, nil) { 170 t.Error("readerContains with nil arguments") 171 } 172 } 173 174 func createZeroSizedFileInTempDir() (File, error) { 175 filePrefix := "_path_test_" 176 f, e := TempFile(testFS, "", filePrefix) // dir is os.TempDir() 177 if e != nil { 178 // if there was an error no file was created. 179 // => no requirement to delete the file 180 return nil, e 181 } 182 return f, nil 183 } 184 185 func createNonZeroSizedFileInTempDir() (File, error) { 186 f, err := createZeroSizedFileInTempDir() 187 if err != nil { 188 // no file ?? 189 } 190 byteString := []byte("byteString") 191 err = WriteFile(testFS, f.Name(), byteString, 0644) 192 if err != nil { 193 // delete the file 194 deleteFileInTempDir(f) 195 return nil, err 196 } 197 return f, nil 198 } 199 200 func deleteFileInTempDir(f File) { 201 err := testFS.Remove(f.Name()) 202 if err != nil { 203 // now what? 204 } 205 } 206 207 func createEmptyTempDir() (string, error) { 208 dirPrefix := "_dir_prefix_" 209 d, e := TempDir(testFS, "", dirPrefix) // will be in os.TempDir() 210 if e != nil { 211 // no directory to delete - it was never created 212 return "", e 213 } 214 return d, nil 215 } 216 217 func createTempDirWithZeroLengthFiles() (string, error) { 218 d, dirErr := createEmptyTempDir() 219 if dirErr != nil { 220 //now what? 221 } 222 filePrefix := "_path_test_" 223 _, fileErr := TempFile(testFS, d, filePrefix) // dir is os.TempDir() 224 if fileErr != nil { 225 // if there was an error no file was created. 226 // but we need to remove the directory to clean-up 227 deleteTempDir(d) 228 return "", fileErr 229 } 230 // the dir now has one, zero length file in it 231 return d, nil 232 233 } 234 235 func createTempDirWithNonZeroLengthFiles() (string, error) { 236 d, dirErr := createEmptyTempDir() 237 if dirErr != nil { 238 //now what? 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, 0644) 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 263 func TestExists(t *testing.T) { 264 zeroSizedFile, _ := createZeroSizedFileInTempDir() 265 defer deleteFileInTempDir(zeroSizedFile) 266 nonZeroSizedFile, _ := createNonZeroSizedFileInTempDir() 267 defer deleteFileInTempDir(nonZeroSizedFile) 268 emptyDirectory, _ := createEmptyTempDir() 269 defer deleteTempDir(emptyDirectory) 270 nonExistentFile := os.TempDir() + "/this-file-does-not-exist.txt" 271 nonExistentDir := os.TempDir() + "/this/direcotry/does/not/exist/" 272 273 type test struct { 274 input string 275 expectedResult bool 276 expectedErr error 277 } 278 279 data := []test{ 280 {zeroSizedFile.Name(), true, nil}, 281 {nonZeroSizedFile.Name(), true, nil}, 282 {emptyDirectory, true, nil}, 283 {nonExistentFile, false, nil}, 284 {nonExistentDir, false, nil}, 285 } 286 for i, d := range data { 287 exists, err := Exists(testFS, d.input) 288 if d.expectedResult != exists { 289 t.Errorf("Test %d failed. Expected result %t got %t", i, d.expectedResult, exists) 290 } 291 if d.expectedErr != err { 292 t.Errorf("Test %d failed. Expected %q got %q", i, d.expectedErr, err) 293 } 294 } 295 296 } 297 298 func TestSafeWriteToDisk(t *testing.T) { 299 emptyFile, _ := createZeroSizedFileInTempDir() 300 defer deleteFileInTempDir(emptyFile) 301 tmpDir, _ := createEmptyTempDir() 302 defer deleteTempDir(tmpDir) 303 304 randomString := "This is a random string!" 305 reader := strings.NewReader(randomString) 306 307 fileExists := fmt.Errorf("%v already exists", emptyFile.Name()) 308 309 type test struct { 310 filename string 311 expectedErr error 312 } 313 314 now := time.Now().Unix() 315 nowStr := strconv.FormatInt(now, 10) 316 data := []test{ 317 {emptyFile.Name(), fileExists}, 318 {tmpDir + "/" + nowStr, nil}, 319 } 320 321 for i, d := range data { 322 e := SafeWriteReader(testFS, d.filename, reader) 323 if d.expectedErr != nil { 324 if d.expectedErr.Error() != e.Error() { 325 t.Errorf("Test %d failed. Expected error %q but got %q", i, d.expectedErr.Error(), e.Error()) 326 } 327 } else { 328 if d.expectedErr != e { 329 t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedErr, e) 330 } 331 contents, _ := ReadFile(testFS, d.filename) 332 if randomString != string(contents) { 333 t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents)) 334 } 335 } 336 reader.Seek(0, 0) 337 } 338 } 339 340 func TestWriteToDisk(t *testing.T) { 341 emptyFile, _ := createZeroSizedFileInTempDir() 342 defer deleteFileInTempDir(emptyFile) 343 tmpDir, _ := createEmptyTempDir() 344 defer deleteTempDir(tmpDir) 345 346 randomString := "This is a random string!" 347 reader := strings.NewReader(randomString) 348 349 type test struct { 350 filename string 351 expectedErr error 352 } 353 354 now := time.Now().Unix() 355 nowStr := strconv.FormatInt(now, 10) 356 data := []test{ 357 {emptyFile.Name(), nil}, 358 {tmpDir + "/" + nowStr, nil}, 359 } 360 361 for i, d := range data { 362 e := WriteReader(testFS, d.filename, reader) 363 if d.expectedErr != e { 364 t.Errorf("Test %d failed. WriteToDisk Error Expected %q but got %q", i, d.expectedErr, e) 365 } 366 contents, e := ReadFile(testFS, d.filename) 367 if e != nil { 368 t.Errorf("Test %d failed. Could not read file %s. Reason: %s\n", i, d.filename, e) 369 } 370 if randomString != string(contents) { 371 t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents)) 372 } 373 reader.Seek(0, 0) 374 } 375 } 376 377 func TestGetTempDir(t *testing.T) { 378 dir := os.TempDir() 379 if FilePathSeparator != dir[len(dir)-1:] { 380 dir = dir + FilePathSeparator 381 } 382 testDir := "hugoTestFolder" + FilePathSeparator 383 tests := []struct { 384 input string 385 expected string 386 }{ 387 {"", dir}, 388 {testDir + " Foo bar ", dir + testDir + " Foo bar " + FilePathSeparator}, 389 {testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + FilePathSeparator}, 390 {testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoo%bAR" + FilePathSeparator}, 391 {testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + FilePathSeparator}, 392 {testDir + "трям/трям", dir + testDir + "трям/трям" + FilePathSeparator}, 393 {testDir + "은행", dir + testDir + "은행" + FilePathSeparator}, 394 {testDir + "Банковский кассир", dir + testDir + "Банковский кассир" + FilePathSeparator}, 395 } 396 397 for _, test := range tests { 398 output := GetTempDir(new(MemMapFs), test.input) 399 if output != test.expected { 400 t.Errorf("Expected %#v, got %#v\n", test.expected, output) 401 } 402 } 403 } 404 405 // This function is very dangerous. Don't use it. 406 func deleteTempDir(d string) { 407 err := os.RemoveAll(d) 408 if err != nil { 409 // now what? 410 } 411 } 412 413 func TestFullBaseFsPath(t *testing.T) { 414 type dirSpec struct { 415 Dir1, Dir2, Dir3 string 416 } 417 dirSpecs := []dirSpec{ 418 dirSpec{Dir1: "/", Dir2: "/", Dir3: "/"}, 419 dirSpec{Dir1: "/", Dir2: "/path2", Dir3: "/"}, 420 dirSpec{Dir1: "/path1/dir", Dir2: "/path2/dir/", Dir3: "/path3/dir"}, 421 dirSpec{Dir1: "C:/path1", Dir2: "path2/dir", Dir3: "/path3/dir/"}, 422 } 423 424 for _, ds := range dirSpecs { 425 memFs := NewMemMapFs() 426 level1Fs := NewBasePathFs(memFs, ds.Dir1) 427 level2Fs := NewBasePathFs(level1Fs, ds.Dir2) 428 level3Fs := NewBasePathFs(level2Fs, ds.Dir3) 429 430 type spec struct { 431 BaseFs Fs 432 FileName string 433 ExpectedPath string 434 } 435 specs := []spec{ 436 spec{BaseFs: level3Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, ds.Dir3, "f.txt")}, 437 spec{BaseFs: level3Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, ds.Dir3, "")}, 438 spec{BaseFs: level2Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, "f.txt")}, 439 spec{BaseFs: level2Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, "")}, 440 spec{BaseFs: level1Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, "f.txt")}, 441 spec{BaseFs: level1Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, "")}, 442 } 443 444 for _, s := range specs { 445 if actualPath := FullBaseFsPath(s.BaseFs.(*BasePathFs), s.FileName); actualPath != s.ExpectedPath { 446 t.Errorf("Expected \n%s got \n%s", s.ExpectedPath, actualPath) 447 } 448 } 449 } 450 }