vendor tsgo
This commit is contained in:
222
tools/tsgo/internal/fswatch/walkdir_test.go
Normal file
222
tools/tsgo/internal/fswatch/walkdir_test.go
Normal file
@@ -0,0 +1,222 @@
|
||||
package fswatch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type walkDirFunc = func(dir string, recursive bool, fn func(string, bool) error) error
|
||||
|
||||
func runWalkDirTest(t *testing.T, fn func(t *testing.T, walk walkDirFunc)) {
|
||||
t.Helper()
|
||||
t.Parallel()
|
||||
for _, rt := range []struct {
|
||||
name string
|
||||
fn walkDirFunc
|
||||
}{
|
||||
{"native", walkDir},
|
||||
{"generic", walkDirGeneric},
|
||||
} {
|
||||
t.Run(rt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
fn(t, rt.fn)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirDoesNotFollowSymlinkedDir(t *testing.T) { //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
runWalkDirTest(t, testWalkDirDoesNotFollowSymlinkedDir)
|
||||
}
|
||||
|
||||
func TestWalkDirDoesNotFollowRootSymlinkedDir(t *testing.T) { //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
runWalkDirTest(t, testWalkDirDoesNotFollowRootSymlinkedDir)
|
||||
}
|
||||
|
||||
func testWalkDirDoesNotFollowRootSymlinkedDir(t *testing.T, walk walkDirFunc) {
|
||||
root := newTmpDir(t)
|
||||
target := filepath.Join(t.TempDir(), "target")
|
||||
if err := os.Mkdir(target, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link := filepath.Join(root, "link")
|
||||
makeDirSymlink(t, target, link)
|
||||
|
||||
if err := walk(link, true, nil); err == nil {
|
||||
t.Fatal("expected error for root symlinked directory")
|
||||
}
|
||||
}
|
||||
|
||||
func testWalkDirDoesNotFollowSymlinkedDir(t *testing.T, walk walkDirFunc) {
|
||||
root := newTmpDir(t)
|
||||
target := filepath.Join(t.TempDir(), "target")
|
||||
if err := os.Mkdir(target, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(target, "child"), []byte("hidden"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
link := filepath.Join(root, "link")
|
||||
makeDirSymlink(t, target, link)
|
||||
|
||||
found := map[string]bool{}
|
||||
if err := walk(root, true, func(path string, isDir bool) error {
|
||||
found[path] = isDir
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
isDir, ok := found[link]
|
||||
if !ok {
|
||||
t.Fatalf("symlink %q missing from walk", link)
|
||||
}
|
||||
if isDir {
|
||||
t.Fatalf("symlink %q was treated as a directory", link)
|
||||
}
|
||||
if _, ok := found[filepath.Join(link, "child")]; ok {
|
||||
t.Fatal("walkDir followed symlinked directory")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirIgnoresUnreadableSubdir(t *testing.T) { //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
runWalkDirTest(t, testWalkDirIgnoresUnreadableSubdir)
|
||||
}
|
||||
|
||||
func testWalkDirIgnoresUnreadableSubdir(t *testing.T, walk walkDirFunc) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("Windows does not enforce POSIX directory permission bits")
|
||||
}
|
||||
if os.Geteuid() == 0 {
|
||||
t.Skip("root can read directories regardless of mode bits")
|
||||
}
|
||||
|
||||
root := newTmpDir(t)
|
||||
denied := filepath.Join(root, "denied")
|
||||
if err := os.Mkdir(denied, 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
child := filepath.Join(denied, "child")
|
||||
if err := os.WriteFile(child, []byte("hidden"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Chmod(denied, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = os.Chmod(denied, 0o700) })
|
||||
|
||||
found := map[string]bool{}
|
||||
if err := walk(root, true, func(path string, isDir bool) error {
|
||||
found[path] = isDir
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := found[denied]; ok {
|
||||
t.Fatalf("unreadable directory should be ignored, found %q", denied)
|
||||
}
|
||||
if _, ok := found[child]; ok {
|
||||
t.Fatalf("unreadable child should be ignored, found %q", child)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirMissingDir(t *testing.T) { runWalkDirTest(t, testWalkDirMissingDir) } //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
func testWalkDirMissingDir(t *testing.T, walk walkDirFunc) {
|
||||
dir := filepath.Join(t.TempDir(), "nonexistent")
|
||||
if err := walk(dir, true, nil); err == nil {
|
||||
t.Fatal("expected error for missing directory")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirNotADir(t *testing.T) { runWalkDirTest(t, testWalkDirNotADir) } //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
func testWalkDirNotADir(t *testing.T, walk walkDirFunc) {
|
||||
f := filepath.Join(t.TempDir(), "file")
|
||||
if err := os.WriteFile(f, []byte("x"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := walk(f, true, nil); err == nil {
|
||||
t.Fatal("expected error for non-directory")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirEntries(t *testing.T) { runWalkDirTest(t, testWalkDirEntries) } //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
func testWalkDirEntries(t *testing.T, walk walkDirFunc) {
|
||||
root := newTmpDir(t)
|
||||
if err := os.WriteFile(filepath.Join(root, "a.txt"), []byte("a"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sub := filepath.Join(root, "sub")
|
||||
if err := os.Mkdir(sub, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(sub, "b.txt"), []byte("b"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
found := map[string]bool{}
|
||||
if err := walk(root, true, func(path string, isDir bool) error {
|
||||
found[path] = isDir
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := found[filepath.Join(root, "a.txt")]; !ok {
|
||||
t.Fatal("missing a.txt")
|
||||
}
|
||||
if _, ok := found[sub]; !ok {
|
||||
t.Fatal("missing sub/")
|
||||
}
|
||||
if _, ok := found[filepath.Join(sub, "b.txt")]; !ok {
|
||||
t.Fatal("missing sub/b.txt")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirCallback(t *testing.T) { runWalkDirTest(t, testWalkDirCallback) } //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
func testWalkDirCallback(t *testing.T, walk walkDirFunc) {
|
||||
root := newTmpDir(t)
|
||||
sub := filepath.Join(root, "sub")
|
||||
if err := os.Mkdir(sub, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(sub, "f.txt"), []byte("f"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var dirs, files []string
|
||||
err := walk(root, true, func(path string, isDir bool) error {
|
||||
if isDir {
|
||||
dirs = append(dirs, path)
|
||||
} else {
|
||||
files = append(files, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(dirs) < 2 {
|
||||
t.Fatalf("expected at least 2 dirs (root + sub), got %d: %v", len(dirs), dirs)
|
||||
}
|
||||
if len(files) < 1 {
|
||||
t.Fatalf("expected at least 1 file, got %d", len(files))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWalkDirCallbackError(t *testing.T) { runWalkDirTest(t, testWalkDirCallbackError) } //nolint:paralleltest // runWalkDirTest calls t.Parallel.
|
||||
func testWalkDirCallbackError(t *testing.T, walk walkDirFunc) {
|
||||
root := newTmpDir(t)
|
||||
if err := os.WriteFile(filepath.Join(root, "a.txt"), []byte("a"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sentinel := errors.New("stop")
|
||||
err := walk(root, true, func(path string, isDir bool) error {
|
||||
return sentinel
|
||||
})
|
||||
if !errors.Is(err, sentinel) {
|
||||
t.Fatalf("expected sentinel error, got %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user