// Copyright ©2015 Steve Francia // 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) } } } }