1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
//go:build !darwin && !(aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris)
package fastwalk
import (
"io/fs"
"math/rand"
"reflect"
"testing"
"time"
"github.com/charlievieth/fastwalk/internal/fmtdirent"
)
var _ DirEntry = dirEntry{}
// Minimal DirEntry for testing
type dirEntry struct {
name string
typ fs.FileMode
}
func (de dirEntry) Name() string { return de.name }
func (de dirEntry) IsDir() bool { return de.typ.IsDir() }
func (de dirEntry) Type() fs.FileMode { return de.typ.Type() }
func (de dirEntry) Depth() int { panic("not implemented") }
func (de dirEntry) Info() (fs.FileInfo, error) { panic("not implemented") }
func (de dirEntry) Stat() (fs.FileInfo, error) { panic("not implemented") }
func (de dirEntry) String() string {
return fmtdirent.FormatDirEntry(de)
}
// NB: this must be kept in sync with the
// TestSortDirents in dirent_unix_test.go
func TestSortDirents(t *testing.T) {
direntNames := func(dents []DirEntry) []string {
names := make([]string, len(dents))
for i, d := range dents {
names[i] = d.Name()
}
return names
}
t.Run("None", func(t *testing.T) {
dents := []DirEntry{
dirEntry{name: "b"},
dirEntry{name: "a"},
dirEntry{name: "d"},
dirEntry{name: "c"},
}
want := direntNames(dents)
sortDirents(SortNone, dents)
got := direntNames(dents)
if !reflect.DeepEqual(got, want) {
t.Errorf("got: %q want: %q", got, want)
}
})
rr := rand.New(rand.NewSource(time.Now().UnixNano()))
shuffleDirents := func(dents []DirEntry) []DirEntry {
rr.Shuffle(len(dents), func(i, j int) {
dents[i], dents[j] = dents[j], dents[i]
})
return dents
}
// dents needs to be in the expected order
test := func(t *testing.T, dents []DirEntry, mode SortMode) {
want := direntNames(dents)
// Run multiple times with different shuffles
for i := 0; i < 10; i++ {
t.Run("", func(t *testing.T) {
sortDirents(mode, shuffleDirents(dents))
got := direntNames(dents)
if !reflect.DeepEqual(got, want) {
t.Errorf("got: %q want: %q", got, want)
}
})
}
}
t.Run("Lexical", func(t *testing.T) {
dents := []DirEntry{
dirEntry{name: "a"},
dirEntry{name: "b"},
dirEntry{name: "c"},
dirEntry{name: "d"},
}
test(t, dents, SortLexical)
})
t.Run("FilesFirst", func(t *testing.T) {
dents := []DirEntry{
// Files lexically
dirEntry{name: "f1", typ: 0},
dirEntry{name: "f2", typ: 0},
dirEntry{name: "f3", typ: 0},
// Non-dirs lexically
dirEntry{name: "a1", typ: fs.ModeSymlink},
dirEntry{name: "a2", typ: fs.ModeSymlink},
dirEntry{name: "a3", typ: fs.ModeSymlink},
dirEntry{name: "s1", typ: fs.ModeSocket},
dirEntry{name: "s2", typ: fs.ModeSocket},
dirEntry{name: "s3", typ: fs.ModeSocket},
// Dirs lexically
dirEntry{name: "d1", typ: fs.ModeDir},
dirEntry{name: "d2", typ: fs.ModeDir},
dirEntry{name: "d3", typ: fs.ModeDir},
}
test(t, dents, SortFilesFirst)
})
t.Run("DirsFirst", func(t *testing.T) {
dents := []DirEntry{
// Dirs lexically
dirEntry{name: "d1", typ: fs.ModeDir},
dirEntry{name: "d2", typ: fs.ModeDir},
dirEntry{name: "d3", typ: fs.ModeDir},
// Files lexically
dirEntry{name: "f1", typ: 0},
dirEntry{name: "f2", typ: 0},
dirEntry{name: "f3", typ: 0},
// Non-dirs lexically
dirEntry{name: "a1", typ: fs.ModeSymlink},
dirEntry{name: "a2", typ: fs.ModeSymlink},
dirEntry{name: "a3", typ: fs.ModeSymlink},
dirEntry{name: "s1", typ: fs.ModeSocket},
dirEntry{name: "s2", typ: fs.ModeSocket},
dirEntry{name: "s3", typ: fs.ModeSocket},
}
test(t, dents, SortDirsFirst)
})
}
|