| // Copyright ©2015 Steve Francia <spf@spf13.com> |
| // Portions Copyright ©2015 The Hugo Authors |
| // |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| package afero |
| |
| import ( |
| "fmt" |
| "os" |
| "path/filepath" |
| "strconv" |
| "strings" |
| "testing" |
| "time" |
| ) |
| |
| var testFS = new(MemMapFs) |
| |
| func TestDirExists(t *testing.T) { |
| type test struct { |
| input string |
| expected bool |
| } |
| |
| // First create a couple directories so there is something in the filesystem |
| //testFS := new(MemMapFs) |
| testFS.MkdirAll("/foo/bar", 0777) |
| |
| data := []test{ |
| {".", true}, |
| {"./", true}, |
| {"..", true}, |
| {"../", true}, |
| {"./..", true}, |
| {"./../", true}, |
| {"/foo/", true}, |
| {"/foo", true}, |
| {"/foo/bar", true}, |
| {"/foo/bar/", true}, |
| {"/", true}, |
| {"/some-really-random-directory-name", false}, |
| {"/some/really/random/directory/name", false}, |
| {"./some-really-random-local-directory-name", false}, |
| {"./some/really/random/local/directory/name", false}, |
| } |
| |
| for i, d := range data { |
| exists, _ := DirExists(testFS, filepath.FromSlash(d.input)) |
| if d.expected != exists { |
| t.Errorf("Test %d %q failed. Expected %t got %t", i, d.input, d.expected, exists) |
| } |
| } |
| } |
| |
| func TestIsDir(t *testing.T) { |
| testFS = new(MemMapFs) |
| |
| type test struct { |
| input string |
| expected bool |
| } |
| data := []test{ |
| {"./", true}, |
| {"/", true}, |
| {"./this-directory-does-not-existi", false}, |
| {"/this-absolute-directory/does-not-exist", false}, |
| } |
| |
| for i, d := range data { |
| |
| exists, _ := IsDir(testFS, d.input) |
| if d.expected != exists { |
| t.Errorf("Test %d failed. Expected %t got %t", i, d.expected, exists) |
| } |
| } |
| } |
| |
| func TestIsEmpty(t *testing.T) { |
| testFS = new(MemMapFs) |
| |
| zeroSizedFile, _ := createZeroSizedFileInTempDir() |
| defer deleteFileInTempDir(zeroSizedFile) |
| nonZeroSizedFile, _ := createNonZeroSizedFileInTempDir() |
| defer deleteFileInTempDir(nonZeroSizedFile) |
| emptyDirectory, _ := createEmptyTempDir() |
| defer deleteTempDir(emptyDirectory) |
| nonEmptyZeroLengthFilesDirectory, _ := createTempDirWithZeroLengthFiles() |
| defer deleteTempDir(nonEmptyZeroLengthFilesDirectory) |
| nonEmptyNonZeroLengthFilesDirectory, _ := createTempDirWithNonZeroLengthFiles() |
| defer deleteTempDir(nonEmptyNonZeroLengthFilesDirectory) |
| nonExistentFile := os.TempDir() + "/this-file-does-not-exist.txt" |
| nonExistentDir := os.TempDir() + "/this/direcotry/does/not/exist/" |
| |
| fileDoesNotExist := fmt.Errorf("%q path does not exist", nonExistentFile) |
| dirDoesNotExist := fmt.Errorf("%q path does not exist", nonExistentDir) |
| |
| type test struct { |
| input string |
| expectedResult bool |
| expectedErr error |
| } |
| |
| data := []test{ |
| {zeroSizedFile.Name(), true, nil}, |
| {nonZeroSizedFile.Name(), false, nil}, |
| {emptyDirectory, true, nil}, |
| {nonEmptyZeroLengthFilesDirectory, false, nil}, |
| {nonEmptyNonZeroLengthFilesDirectory, false, nil}, |
| {nonExistentFile, false, fileDoesNotExist}, |
| {nonExistentDir, false, dirDoesNotExist}, |
| } |
| for i, d := range data { |
| exists, err := IsEmpty(testFS, d.input) |
| if d.expectedResult != exists { |
| t.Errorf("Test %d %q failed exists. Expected result %t got %t", i, d.input, d.expectedResult, exists) |
| } |
| if d.expectedErr != nil { |
| if d.expectedErr.Error() != err.Error() { |
| t.Errorf("Test %d failed with err. Expected %q(%#v) got %q(%#v)", i, d.expectedErr, d.expectedErr, err, err) |
| } |
| } else { |
| if d.expectedErr != err { |
| t.Errorf("Test %d failed. Expected error %q(%#v) got %q(%#v)", i, d.expectedErr, d.expectedErr, err, err) |
| } |
| } |
| } |
| } |
| |
| func TestReaderContains(t *testing.T) { |
| for i, this := range []struct { |
| v1 string |
| v2 [][]byte |
| expect bool |
| }{ |
| {"abc", [][]byte{[]byte("a")}, true}, |
| {"abc", [][]byte{[]byte("b")}, true}, |
| {"abcdefg", [][]byte{[]byte("efg")}, true}, |
| {"abc", [][]byte{[]byte("d")}, false}, |
| {"abc", [][]byte{[]byte("d"), []byte("e")}, false}, |
| {"abc", [][]byte{[]byte("d"), []byte("a")}, true}, |
| {"abc", [][]byte{[]byte("b"), []byte("e")}, true}, |
| {"", nil, false}, |
| {"", [][]byte{[]byte("a")}, false}, |
| {"a", [][]byte{[]byte("")}, false}, |
| {"", [][]byte{[]byte("")}, false}} { |
| result := readerContainsAny(strings.NewReader(this.v1), this.v2...) |
| if result != this.expect { |
| t.Errorf("[%d] readerContains: got %t but expected %t", i, result, this.expect) |
| } |
| } |
| |
| if readerContainsAny(nil, []byte("a")) { |
| t.Error("readerContains with nil reader") |
| } |
| |
| if readerContainsAny(nil, nil) { |
| t.Error("readerContains with nil arguments") |
| } |
| } |
| |
| func createZeroSizedFileInTempDir() (File, error) { |
| filePrefix := "_path_test_" |
| f, e := TempFile(testFS, "", filePrefix) // dir is os.TempDir() |
| if e != nil { |
| // if there was an error no file was created. |
| // => no requirement to delete the file |
| return nil, e |
| } |
| return f, nil |
| } |
| |
| func createNonZeroSizedFileInTempDir() (File, error) { |
| f, err := createZeroSizedFileInTempDir() |
| if err != nil { |
| // no file ?? |
| } |
| byteString := []byte("byteString") |
| err = WriteFile(testFS, f.Name(), byteString, 0644) |
| if err != nil { |
| // delete the file |
| deleteFileInTempDir(f) |
| return nil, err |
| } |
| return f, nil |
| } |
| |
| func deleteFileInTempDir(f File) { |
| err := testFS.Remove(f.Name()) |
| if err != nil { |
| // now what? |
| } |
| } |
| |
| func createEmptyTempDir() (string, error) { |
| dirPrefix := "_dir_prefix_" |
| d, e := TempDir(testFS, "", dirPrefix) // will be in os.TempDir() |
| if e != nil { |
| // no directory to delete - it was never created |
| return "", e |
| } |
| return d, nil |
| } |
| |
| func createTempDirWithZeroLengthFiles() (string, error) { |
| d, dirErr := createEmptyTempDir() |
| if dirErr != nil { |
| //now what? |
| } |
| filePrefix := "_path_test_" |
| _, fileErr := TempFile(testFS, d, filePrefix) // dir is os.TempDir() |
| if fileErr != nil { |
| // if there was an error no file was created. |
| // but we need to remove the directory to clean-up |
| deleteTempDir(d) |
| return "", fileErr |
| } |
| // the dir now has one, zero length file in it |
| return d, nil |
| |
| } |
| |
| func createTempDirWithNonZeroLengthFiles() (string, error) { |
| d, dirErr := createEmptyTempDir() |
| if dirErr != nil { |
| //now what? |
| } |
| filePrefix := "_path_test_" |
| f, fileErr := TempFile(testFS, d, filePrefix) // dir is os.TempDir() |
| if fileErr != nil { |
| // if there was an error no file was created. |
| // but we need to remove the directory to clean-up |
| deleteTempDir(d) |
| return "", fileErr |
| } |
| byteString := []byte("byteString") |
| fileErr = WriteFile(testFS, f.Name(), byteString, 0644) |
| if fileErr != nil { |
| // delete the file |
| deleteFileInTempDir(f) |
| // also delete the directory |
| deleteTempDir(d) |
| return "", fileErr |
| } |
| |
| // the dir now has one, zero length file in it |
| return d, nil |
| |
| } |
| |
| func TestExists(t *testing.T) { |
| zeroSizedFile, _ := createZeroSizedFileInTempDir() |
| defer deleteFileInTempDir(zeroSizedFile) |
| nonZeroSizedFile, _ := createNonZeroSizedFileInTempDir() |
| defer deleteFileInTempDir(nonZeroSizedFile) |
| emptyDirectory, _ := createEmptyTempDir() |
| defer deleteTempDir(emptyDirectory) |
| nonExistentFile := os.TempDir() + "/this-file-does-not-exist.txt" |
| nonExistentDir := os.TempDir() + "/this/direcotry/does/not/exist/" |
| |
| type test struct { |
| input string |
| expectedResult bool |
| expectedErr error |
| } |
| |
| data := []test{ |
| {zeroSizedFile.Name(), true, nil}, |
| {nonZeroSizedFile.Name(), true, nil}, |
| {emptyDirectory, true, nil}, |
| {nonExistentFile, false, nil}, |
| {nonExistentDir, false, nil}, |
| } |
| for i, d := range data { |
| exists, err := Exists(testFS, d.input) |
| if d.expectedResult != exists { |
| t.Errorf("Test %d failed. Expected result %t got %t", i, d.expectedResult, exists) |
| } |
| if d.expectedErr != err { |
| t.Errorf("Test %d failed. Expected %q got %q", i, d.expectedErr, err) |
| } |
| } |
| |
| } |
| |
| func TestSafeWriteToDisk(t *testing.T) { |
| emptyFile, _ := createZeroSizedFileInTempDir() |
| defer deleteFileInTempDir(emptyFile) |
| tmpDir, _ := createEmptyTempDir() |
| defer deleteTempDir(tmpDir) |
| |
| randomString := "This is a random string!" |
| reader := strings.NewReader(randomString) |
| |
| fileExists := fmt.Errorf("%v already exists", emptyFile.Name()) |
| |
| type test struct { |
| filename string |
| expectedErr error |
| } |
| |
| now := time.Now().Unix() |
| nowStr := strconv.FormatInt(now, 10) |
| data := []test{ |
| {emptyFile.Name(), fileExists}, |
| {tmpDir + "/" + nowStr, nil}, |
| } |
| |
| for i, d := range data { |
| e := SafeWriteReader(testFS, d.filename, reader) |
| if d.expectedErr != nil { |
| if d.expectedErr.Error() != e.Error() { |
| t.Errorf("Test %d failed. Expected error %q but got %q", i, d.expectedErr.Error(), e.Error()) |
| } |
| } else { |
| if d.expectedErr != e { |
| t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedErr, e) |
| } |
| contents, _ := ReadFile(testFS, d.filename) |
| if randomString != string(contents) { |
| t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents)) |
| } |
| } |
| reader.Seek(0, 0) |
| } |
| } |
| |
| func TestWriteToDisk(t *testing.T) { |
| emptyFile, _ := createZeroSizedFileInTempDir() |
| defer deleteFileInTempDir(emptyFile) |
| tmpDir, _ := createEmptyTempDir() |
| defer deleteTempDir(tmpDir) |
| |
| randomString := "This is a random string!" |
| reader := strings.NewReader(randomString) |
| |
| type test struct { |
| filename string |
| expectedErr error |
| } |
| |
| now := time.Now().Unix() |
| nowStr := strconv.FormatInt(now, 10) |
| data := []test{ |
| {emptyFile.Name(), nil}, |
| {tmpDir + "/" + nowStr, nil}, |
| } |
| |
| for i, d := range data { |
| e := WriteReader(testFS, d.filename, reader) |
| if d.expectedErr != e { |
| t.Errorf("Test %d failed. WriteToDisk Error Expected %q but got %q", i, d.expectedErr, e) |
| } |
| contents, e := ReadFile(testFS, d.filename) |
| if e != nil { |
| t.Errorf("Test %d failed. Could not read file %s. Reason: %s\n", i, d.filename, e) |
| } |
| if randomString != string(contents) { |
| t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents)) |
| } |
| reader.Seek(0, 0) |
| } |
| } |
| |
| func TestGetTempDir(t *testing.T) { |
| dir := os.TempDir() |
| if FilePathSeparator != dir[len(dir)-1:] { |
| dir = dir + FilePathSeparator |
| } |
| testDir := "hugoTestFolder" + FilePathSeparator |
| tests := []struct { |
| input string |
| expected string |
| }{ |
| {"", dir}, |
| {testDir + " Foo bar ", dir + testDir + " Foo bar " + FilePathSeparator}, |
| {testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + FilePathSeparator}, |
| {testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoo%bAR" + FilePathSeparator}, |
| {testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + FilePathSeparator}, |
| {testDir + "трям/трям", dir + testDir + "трям/трям" + FilePathSeparator}, |
| {testDir + "은행", dir + testDir + "은행" + FilePathSeparator}, |
| {testDir + "Банковский кассир", dir + testDir + "Банковский кассир" + FilePathSeparator}, |
| } |
| |
| for _, test := range tests { |
| output := GetTempDir(new(MemMapFs), test.input) |
| if output != test.expected { |
| t.Errorf("Expected %#v, got %#v\n", test.expected, output) |
| } |
| } |
| } |
| |
| // This function is very dangerous. Don't use it. |
| func deleteTempDir(d string) { |
| err := os.RemoveAll(d) |
| if err != nil { |
| // now what? |
| } |
| } |
| |
| func TestFullBaseFsPath(t *testing.T) { |
| type dirSpec struct { |
| Dir1, Dir2, Dir3 string |
| } |
| dirSpecs := []dirSpec{ |
| dirSpec{Dir1: "/", Dir2: "/", Dir3: "/"}, |
| dirSpec{Dir1: "/", Dir2: "/path2", Dir3: "/"}, |
| dirSpec{Dir1: "/path1/dir", Dir2: "/path2/dir/", Dir3: "/path3/dir"}, |
| dirSpec{Dir1: "C:/path1", Dir2: "path2/dir", Dir3: "/path3/dir/"}, |
| } |
| |
| for _, ds := range dirSpecs { |
| memFs := NewMemMapFs() |
| level1Fs := NewBasePathFs(memFs, ds.Dir1) |
| level2Fs := NewBasePathFs(level1Fs, ds.Dir2) |
| level3Fs := NewBasePathFs(level2Fs, ds.Dir3) |
| |
| type spec struct { |
| BaseFs Fs |
| FileName string |
| ExpectedPath string |
| } |
| specs := []spec{ |
| spec{BaseFs: level3Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, ds.Dir3, "f.txt")}, |
| spec{BaseFs: level3Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, ds.Dir3, "")}, |
| spec{BaseFs: level2Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, "f.txt")}, |
| spec{BaseFs: level2Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, ds.Dir2, "")}, |
| spec{BaseFs: level1Fs, FileName: "f.txt", ExpectedPath: filepath.Join(ds.Dir1, "f.txt")}, |
| spec{BaseFs: level1Fs, FileName: "", ExpectedPath: filepath.Join(ds.Dir1, "")}, |
| } |
| |
| for _, s := range specs { |
| if actualPath := FullBaseFsPath(s.BaseFs.(*BasePathFs), s.FileName); actualPath != s.ExpectedPath { |
| t.Errorf("Expected \n%s got \n%s", s.ExpectedPath, actualPath) |
| } |
| } |
| } |
| } |