mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-14 02:57:52 +08:00
9ce24d616e
- Don't skip glob_test on Windows. - Document the change as a breaking change.
164 lines
4.2 KiB
Go
164 lines
4.2 KiB
Go
package glob
|
|
|
|
import (
|
|
"os"
|
|
"reflect"
|
|
"runtime"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
|
|
"src.elv.sh/pkg/testutil"
|
|
)
|
|
|
|
var (
|
|
mkdirs = []string{"a", "b", "c", "d1", "d1/e", "d1/e/f", "d1/e/f/g",
|
|
"d2", "d2/e", "d2/e/f", "d2/e/f/g"}
|
|
mkdirDots = []string{".el"}
|
|
creates = []string{"a/X", "a/Y", "b/X", "c/Y",
|
|
"dX", "dXY",
|
|
"lorem", "ipsum",
|
|
"d1/e/f/g/X", "d2/e/f/g/X"}
|
|
createDots = []string{".x", ".el/x"}
|
|
symlinks = []struct {
|
|
path string
|
|
target string
|
|
}{
|
|
{"d1/s-f", "f"},
|
|
{"s-d", "d2"},
|
|
{"s-d-f", "d1/f"},
|
|
{"s-bad", "bad"},
|
|
}
|
|
)
|
|
|
|
type globCase struct {
|
|
pattern string
|
|
want []string
|
|
}
|
|
|
|
var globCases = []globCase{
|
|
{"*", []string{"a", "b", "c", "d1", "d2", "dX", "dXY", "lorem", "ipsum", "s-bad", "s-d", "s-d-f"}},
|
|
{".", []string{"."}},
|
|
{"./*", []string{"./a", "./b", "./c", "./d1", "./d2", "./dX", "./dXY", "./lorem", "./ipsum", "./s-bad", "./s-d", "./s-d-f"}},
|
|
{"..", []string{".."}},
|
|
{"a/..", []string{"a/.."}},
|
|
{"a/../*", []string{"a/../a", "a/../b", "a/../c", "a/../d1", "a/../d2", "a/../dX", "a/../dXY", "a/../ipsum", "a/../lorem", "a/../s-bad", "a/../s-d", "a/../s-d-f"}},
|
|
{"*/", []string{"a/", "b/", "c/", "d1/", "d2/"}},
|
|
{"**", []string{"a", "a/X", "a/Y", "b", "b/X", "c", "c/Y", "d1", "d1/e", "d1/e/f", "d1/e/f/g", "d1/e/f/g/X", "d1/s-f", "d2", "d2/e", "d2/e/f", "d2/e/f/g", "d2/e/f/g/X", "dX", "dXY", "ipsum", "lorem", "s-bad", "s-d", "s-d-f"}},
|
|
{"*/X", []string{"a/X", "b/X"}},
|
|
{"**X", []string{"a/X", "b/X", "dX", "d1/e/f/g/X", "d2/e/f/g/X"}},
|
|
{"*/*/*", []string{"d1/e/f", "d2/e/f"}},
|
|
{"l*m", []string{"lorem"}},
|
|
{"d*", []string{"d1", "d2", "dX", "dXY"}},
|
|
{"d*/", []string{"d1/", "d2/"}},
|
|
{"d**", []string{"d1", "d1/e", "d1/e/f", "d1/e/f/g", "d1/e/f/g/X", "d1/s-f", "d2", "d2/e", "d2/e/f", "d2/e/f/g", "d2/e/f/g/X", "dX", "dXY"}},
|
|
{"?", []string{"a", "b", "c"}},
|
|
{"??", []string{"d1", "d2", "dX"}},
|
|
|
|
// Nonexistent paths.
|
|
{"xxxx", []string{}},
|
|
{"xxxx/*", []string{}},
|
|
{"a/*/", []string{}},
|
|
|
|
// TODO Test cases against dotfiles.
|
|
}
|
|
|
|
func TestGlob_Relative(t *testing.T) {
|
|
testGlob(t, false)
|
|
}
|
|
|
|
func TestGlob_Absolute(t *testing.T) {
|
|
testGlob(t, true)
|
|
}
|
|
|
|
func testGlob(t *testing.T, abs bool) {
|
|
dir := testutil.InTempDir(t)
|
|
dir = strings.ReplaceAll(dir, string(os.PathSeparator), "/")
|
|
|
|
for _, dir := range append(mkdirs, mkdirDots...) {
|
|
err := os.Mkdir(dir, 0755)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
for _, file := range append(creates, createDots...) {
|
|
f, err := os.Create(file)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
f.Close()
|
|
}
|
|
for _, link := range symlinks {
|
|
err := os.Symlink(link.target, link.path)
|
|
if err != nil {
|
|
// Creating symlinks requires a special permission on Windows. If
|
|
// the user doesn't have that permission, create the symlink as an
|
|
// ordinary file instead.
|
|
f, err := os.Create(link.path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
f.Close()
|
|
}
|
|
}
|
|
|
|
for _, tc := range globCases {
|
|
pattern := tc.pattern
|
|
if abs {
|
|
pattern = dir + "/" + pattern
|
|
}
|
|
wantResults := make([]string, len(tc.want))
|
|
for i, result := range tc.want {
|
|
if abs {
|
|
wantResults[i] = dir + "/" + result
|
|
} else {
|
|
wantResults[i] = result
|
|
}
|
|
}
|
|
sort.Strings(wantResults)
|
|
|
|
results := globPaths(pattern)
|
|
|
|
if !reflect.DeepEqual(results, wantResults) {
|
|
t.Errorf(`Glob(%q) => %v, want %v`, pattern, results, wantResults)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Regression test for b.elv.sh/1220
|
|
func TestGlob_InvalidUTF8InFilename(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
// On Windows, filenames are converted to UTF-16 before being passed
|
|
// to API calls, meaning that all the invalid byte sequences will be
|
|
// normalized to U+FFFD, making this impossible to test.
|
|
t.Skip()
|
|
}
|
|
|
|
testutil.InTempDir(t)
|
|
|
|
name := string([]byte{255}) + "x"
|
|
f, err := os.Create(name)
|
|
if err != nil {
|
|
// The system may refuse to create a file whose name is not UTF-8. This
|
|
// happens on macOS 11 with an APFS filesystem.
|
|
t.Skip("create: ", err)
|
|
}
|
|
f.Close()
|
|
|
|
paths := globPaths("*x")
|
|
wantPaths := []string{name}
|
|
if !reflect.DeepEqual(paths, wantPaths) {
|
|
t.Errorf("got %v, want %v", paths, wantPaths)
|
|
}
|
|
}
|
|
|
|
func globPaths(pattern string) []string {
|
|
paths := []string{}
|
|
Glob(pattern, func(pathInfo PathInfo) bool {
|
|
paths = append(paths, pathInfo.Path)
|
|
return true
|
|
})
|
|
sort.Strings(paths)
|
|
return paths
|
|
}
|