292 lines
6.6 KiB
Go
292 lines
6.6 KiB
Go
package fileio
|
|
|
|
import (
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestCopyFiles(t *testing.T) {
|
|
// Create a temporary directory for testing
|
|
srcDir, err := os.MkdirTemp("", "src")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(srcDir)
|
|
|
|
// Create a source file
|
|
srcFile := filepath.Join(srcDir, "source.txt")
|
|
err = os.WriteFile(srcFile, []byte("test data"), 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Specify the destination directory
|
|
dstDir, err := os.MkdirTemp("", "dst")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(dstDir)
|
|
|
|
// Call the CopyFiles function
|
|
const perm = fs.FileMode(0444)
|
|
pattern := filepath.Join(srcDir, "*.txt")
|
|
err = CopyFiles(pattern, dstDir, perm)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Verify that the file was copied correctly
|
|
dstFile := filepath.Join(dstDir, "source.txt")
|
|
fileInfo, err := os.Stat(dstFile)
|
|
if err != nil {
|
|
t.Fatalf("file not copied: %s", err)
|
|
}
|
|
if fileInfo.Mode() != perm {
|
|
t.Errorf("unexpected file permissions: got %v, want %v", fileInfo.Mode(), perm)
|
|
}
|
|
|
|
// Read the contents of the copied file
|
|
data, err := os.ReadFile(dstFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Verify the contents of the copied file
|
|
expected := []byte("test data")
|
|
if string(data) != string(expected) {
|
|
t.Errorf("unexpected file content: got %q, want %q", data, expected)
|
|
}
|
|
}
|
|
|
|
func TestReadJson(t *testing.T) {
|
|
type Person struct{ Name string }
|
|
|
|
t.Run("valid", func(t *testing.T) {
|
|
got, err := ReadJson[Person](filepath.Join("testdata", "valid.json"))
|
|
if err != nil {
|
|
t.Fatalf("unexpected error %v", err)
|
|
}
|
|
want := Person{"alice"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("expected %v, got %v", want, got)
|
|
}
|
|
})
|
|
t.Run("invalid", func(t *testing.T) {
|
|
_, err := ReadJson[Person](filepath.Join("testdata", "invalid.json"))
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
})
|
|
t.Run("does not exist", func(t *testing.T) {
|
|
_, err := ReadJson[Person](filepath.Join("testdata", "missing.json"))
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestWriteFile(t *testing.T) {
|
|
dir, err := os.MkdirTemp("", "files")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(dir)
|
|
|
|
t.Run("text", func(t *testing.T) {
|
|
path := filepath.Join(dir, "data.txt")
|
|
err = WriteFile(path, "hello", 0444)
|
|
if err != nil {
|
|
t.Fatalf("expected nil err, got %v", err)
|
|
}
|
|
got, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("read file: expected nil err, got %v", err)
|
|
}
|
|
want := []byte("hello")
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("read file: expected %v, got %v", want, got)
|
|
}
|
|
})
|
|
|
|
t.Run("binary", func(t *testing.T) {
|
|
path := filepath.Join(dir, "data.bin")
|
|
err = WriteFile(path, "data:application/octet-stream;base64,MTIz", 0444)
|
|
if err != nil {
|
|
t.Fatalf("expected nil err, got %v", err)
|
|
}
|
|
got, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("read file: expected nil err, got %v", err)
|
|
}
|
|
want := []byte("123")
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("read file: expected %v, got %v", want, got)
|
|
}
|
|
})
|
|
|
|
t.Run("perm", func(t *testing.T) {
|
|
const perm = 0444
|
|
path := filepath.Join(dir, "perm.txt")
|
|
err = WriteFile(path, "hello", perm)
|
|
if err != nil {
|
|
t.Fatalf("expected nil err, got %v", err)
|
|
}
|
|
fileInfo, err := os.Stat(path)
|
|
if err != nil {
|
|
t.Fatalf("file not created: %s", err)
|
|
}
|
|
if fileInfo.Mode().Perm() != perm {
|
|
t.Errorf("unexpected file permissions: expected %o, got %o", perm, fileInfo.Mode().Perm())
|
|
}
|
|
})
|
|
|
|
t.Run("missing data-url separator", func(t *testing.T) {
|
|
path := filepath.Join(dir, "data.bin")
|
|
err = WriteFile(path, "data:application/octet-stream:MTIz", 0444)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
})
|
|
|
|
t.Run("invalid binary value", func(t *testing.T) {
|
|
path := filepath.Join(dir, "data.bin")
|
|
err = WriteFile(path, "data:application/octet-stream;base64,12345", 0444)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestJoinDir(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
dir string
|
|
filename string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "regular join",
|
|
dir: "/home/user",
|
|
filename: "docs/report.txt",
|
|
want: "/home/user/docs/report.txt",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "join with dot",
|
|
dir: "/home/user",
|
|
filename: ".",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "join with absolute path",
|
|
dir: "/home/user",
|
|
filename: "/etc/passwd",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "join with parent directory",
|
|
dir: "/home/user",
|
|
filename: "../user2/docs/report.txt",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "empty directory",
|
|
dir: "",
|
|
filename: "report.txt",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "empty filename",
|
|
dir: "/home/user",
|
|
filename: "",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "directory with trailing slash",
|
|
dir: "/home/user/",
|
|
filename: "docs/report.txt",
|
|
want: "/home/user/docs/report.txt",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "filename with leading slash",
|
|
dir: "/home/user",
|
|
filename: "/docs/report.txt",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "root directory",
|
|
dir: "/",
|
|
filename: "report.txt",
|
|
want: "/report.txt",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "dot dot slash filename",
|
|
dir: "/home/user",
|
|
filename: "..",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := JoinDir(tt.dir, tt.filename)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("JoinDir() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("JoinDir() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMkdirTemp(t *testing.T) {
|
|
t.Run("default permissions", func(t *testing.T) {
|
|
const perm = 0755
|
|
dir, err := MkdirTemp(perm)
|
|
if err != nil {
|
|
t.Fatalf("failed to create temp directory: %v", err)
|
|
}
|
|
defer os.Remove(dir)
|
|
|
|
info, err := os.Stat(dir)
|
|
if err != nil {
|
|
t.Fatalf("failed to stat temp directory: %v", err)
|
|
}
|
|
if info.Mode().Perm() != perm {
|
|
t.Errorf("unexpected permissions: expected %o, got %o", perm, info.Mode().Perm())
|
|
}
|
|
})
|
|
|
|
t.Run("non-default permissions", func(t *testing.T) {
|
|
const perm = 0777
|
|
dir, err := MkdirTemp(perm)
|
|
if err != nil {
|
|
t.Fatalf("failed to create temp directory: %v", err)
|
|
}
|
|
defer os.Remove(dir)
|
|
|
|
info, err := os.Stat(dir)
|
|
if err != nil {
|
|
t.Fatalf("failed to stat temp directory: %v", err)
|
|
}
|
|
if info.Mode().Perm() != perm {
|
|
t.Errorf("unexpected permissions: expected %o, got %o", perm, info.Mode().Perm())
|
|
}
|
|
})
|
|
}
|