// Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package webdav import ( "fmt" "path/filepath" "strings" "testing" ) func TestDir(t *testing.T) { testCases := []struct { dir, name, want string }{ {"/", "", "/"}, {"/", "/", "/"}, {"/", ".", "/"}, {"/", "./a", "/a"}, {"/", "..", "/"}, {"/", "..", "/"}, {"/", "../", "/"}, {"/", "../.", "/"}, {"/", "../a", "/a"}, {"/", "../..", "/"}, {"/", "../bar/a", "/bar/a"}, {"/", "../baz/a", "/baz/a"}, {"/", "...", "/..."}, {"/", ".../a", "/.../a"}, {"/", ".../..", "/"}, {"/", "a", "/a"}, {"/", "a/./b", "/a/b"}, {"/", "a/../../b", "/b"}, {"/", "a/../b", "/b"}, {"/", "a/b", "/a/b"}, {"/", "a/b/c/../../d", "/a/d"}, {"/", "a/b/c/../../../d", "/d"}, {"/", "a/b/c/../../../../d", "/d"}, {"/", "a/b/c/d", "/a/b/c/d"}, {"/foo/bar", "", "/foo/bar"}, {"/foo/bar", "/", "/foo/bar"}, {"/foo/bar", ".", "/foo/bar"}, {"/foo/bar", "./a", "/foo/bar/a"}, {"/foo/bar", "..", "/foo/bar"}, {"/foo/bar", "../", "/foo/bar"}, {"/foo/bar", "../.", "/foo/bar"}, {"/foo/bar", "../a", "/foo/bar/a"}, {"/foo/bar", "../..", "/foo/bar"}, {"/foo/bar", "../bar/a", "/foo/bar/bar/a"}, {"/foo/bar", "../baz/a", "/foo/bar/baz/a"}, {"/foo/bar", "...", "/foo/bar/..."}, {"/foo/bar", ".../a", "/foo/bar/.../a"}, {"/foo/bar", ".../..", "/foo/bar"}, {"/foo/bar", "a", "/foo/bar/a"}, {"/foo/bar", "a/./b", "/foo/bar/a/b"}, {"/foo/bar", "a/../../b", "/foo/bar/b"}, {"/foo/bar", "a/../b", "/foo/bar/b"}, {"/foo/bar", "a/b", "/foo/bar/a/b"}, {"/foo/bar", "a/b/c/../../d", "/foo/bar/a/d"}, {"/foo/bar", "a/b/c/../../../d", "/foo/bar/d"}, {"/foo/bar", "a/b/c/../../../../d", "/foo/bar/d"}, {"/foo/bar", "a/b/c/d", "/foo/bar/a/b/c/d"}, {"/foo/bar/", "", "/foo/bar"}, {"/foo/bar/", "/", "/foo/bar"}, {"/foo/bar/", ".", "/foo/bar"}, {"/foo/bar/", "./a", "/foo/bar/a"}, {"/foo/bar/", "..", "/foo/bar"}, {"/foo//bar///", "", "/foo/bar"}, {"/foo//bar///", "/", "/foo/bar"}, {"/foo//bar///", ".", "/foo/bar"}, {"/foo//bar///", "./a", "/foo/bar/a"}, {"/foo//bar///", "..", "/foo/bar"}, {"/x/y/z", "ab/c\x00d/ef", ""}, {".", "", "."}, {".", "/", "."}, {".", ".", "."}, {".", "./a", "a"}, {".", "..", "."}, {".", "..", "."}, {".", "../", "."}, {".", "../.", "."}, {".", "../a", "a"}, {".", "../..", "."}, {".", "../bar/a", "bar/a"}, {".", "../baz/a", "baz/a"}, {".", "...", "..."}, {".", ".../a", ".../a"}, {".", ".../..", "."}, {".", "a", "a"}, {".", "a/./b", "a/b"}, {".", "a/../../b", "b"}, {".", "a/../b", "b"}, {".", "a/b", "a/b"}, {".", "a/b/c/../../d", "a/d"}, {".", "a/b/c/../../../d", "d"}, {".", "a/b/c/../../../../d", "d"}, {".", "a/b/c/d", "a/b/c/d"}, {"", "", "."}, {"", "/", "."}, {"", ".", "."}, {"", "./a", "a"}, {"", "..", "."}, } for _, tc := range testCases { d := Dir(filepath.FromSlash(tc.dir)) if got := filepath.ToSlash(d.resolve(tc.name)); got != tc.want { t.Errorf("dir=%q, name=%q: got %q, want %q", tc.dir, tc.name, got, tc.want) } } } func TestWalk(t *testing.T) { type walkStep struct { name, frag string final bool } testCases := []struct { dir string want []walkStep }{ {"", []walkStep{ {"", "", true}, }}, {"/", []walkStep{ {"", "", true}, }}, {"/a", []walkStep{ {"", "a", true}, }}, {"/a/", []walkStep{ {"", "a", true}, }}, {"/a/b", []walkStep{ {"", "a", false}, {"a", "b", true}, }}, {"/a/b/", []walkStep{ {"", "a", false}, {"a", "b", true}, }}, {"/a/b/c", []walkStep{ {"", "a", false}, {"a", "b", false}, {"b", "c", true}, }}, // The following test case is the one mentioned explicitly // in the method description. {"/foo/bar/x", []walkStep{ {"", "foo", false}, {"foo", "bar", false}, {"bar", "x", true}, }}, } for _, tc := range testCases { fs := NewMemFS().(*memFS) parts := strings.Split(tc.dir, "/") for p := 2; p < len(parts); p++ { d := strings.Join(parts[:p], "/") if err := fs.Mkdir(d, 0666); err != nil { t.Errorf("tc.dir=%q: mkdir: %q: %v", tc.dir, d, err) } } i := 0 err := fs.walk("test", tc.dir, func(dir *memFSNode, frag string, final bool) error { got := walkStep{ name: dir.name, frag: frag, final: final, } want := tc.want[i] if got != want { return fmt.Errorf("got %+v, want %+v", got, want) } i++ return nil }) if err != nil { t.Errorf("tc.dir=%q: %v", tc.dir, err) } } }