451 lines
13 KiB
Go
451 lines
13 KiB
Go
|
// 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)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|