// 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 util import ( "fmt" "os" "path/filepath" "strconv" "strings" "testing" "time" "github.com/spf13/afero" ) var testFS = new(afero.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(afero.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(filepath.FromSlash(d.input), testFS) 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(afero.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(d.input, testFS) if d.expected != exists { t.Errorf("Test %d failed. Expected %t got %t", i, d.expected, exists) } } } func TestIsEmpty(t *testing.T) { testFS = new(afero.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(d.input, testFS) 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 createZeroSizedFileInTempDir() (afero.File, error) { filePrefix := "_path_test_" f, e := TempFile("", filePrefix, testFS) // 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() (afero.File, error) { f, err := createZeroSizedFileInTempDir() if err != nil { // no file ?? } byteString := []byte("byteString") err = WriteFile(f.Name(), byteString, 0644, testFS) if err != nil { // delete the file deleteFileInTempDir(f) return nil, err } return f, nil } func deleteFileInTempDir(f afero.File) { err := testFS.Remove(f.Name()) if err != nil { // now what? } } func createEmptyTempDir() (string, error) { dirPrefix := "_dir_prefix_" d, e := TempDir("", dirPrefix, testFS) // 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(d, filePrefix, testFS) // 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(d, filePrefix, testFS) // 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(f.Name(), byteString, 0644, testFS) 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(d.input, testFS) 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(d.filename, reader, testFS) 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(d.filename, testFS) 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(d.filename, reader, testFS) if d.expectedErr != e { t.Errorf("Test %d failed. WriteToDisk Error Expected %q but got %q", i, d.expectedErr, e) } contents, e := ReadFile(d.filename, testFS) 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(test.input, new(afero.MemMapFs)) 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? } }