github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/go/str/str_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package str 6 7 import ( 8 "os" 9 "path/filepath" 10 "runtime" 11 "strings" 12 "testing" 13 ) 14 15 var foldDupTests = []struct { 16 list []string 17 f1, f2 string 18 }{ 19 {StringList("math/rand", "math/big"), "", ""}, 20 {StringList("math", "strings"), "", ""}, 21 {StringList("strings"), "", ""}, 22 {StringList("strings", "strings"), "strings", "strings"}, 23 {StringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"}, 24 } 25 26 func TestFoldDup(t *testing.T) { 27 for _, tt := range foldDupTests { 28 f1, f2 := FoldDup(tt.list) 29 if f1 != tt.f1 || f2 != tt.f2 { 30 t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2) 31 } 32 } 33 } 34 35 func TestHasPathPrefix(t *testing.T) { 36 type testCase struct { 37 s, prefix string 38 want bool 39 } 40 for _, tt := range []testCase{ 41 {"", "", true}, 42 {"", "/", false}, 43 {"foo", "", true}, 44 {"foo", "/", false}, 45 {"foo", "foo", true}, 46 {"foo", "foo/", false}, 47 {"foo", "/foo", false}, 48 {"foo/bar", "", true}, 49 {"foo/bar", "foo", true}, 50 {"foo/bar", "foo/", true}, 51 {"foo/bar", "/foo", false}, 52 {"foo/bar", "foo/bar", true}, 53 {"foo/bar", "foo/bar/", false}, 54 {"foo/bar", "/foo/bar", false}, 55 } { 56 got := HasPathPrefix(tt.s, tt.prefix) 57 if got != tt.want { 58 t.Errorf("HasPathPrefix(%q, %q) = %v; want %v", tt.s, tt.prefix, got, tt.want) 59 } 60 } 61 } 62 63 func TestTrimFilePathPrefixSlash(t *testing.T) { 64 if os.PathSeparator != '/' { 65 t.Skipf("test requires slash-separated file paths") 66 } 67 68 type testCase struct { 69 s, prefix, want string 70 } 71 for _, tt := range []testCase{ 72 {"/", "", "/"}, 73 {"/", "/", ""}, 74 {"/foo", "", "/foo"}, 75 {"/foo", "/", "foo"}, 76 {"/foo", "/foo", ""}, 77 {"/foo/bar", "/foo", "bar"}, 78 {"/foo/bar", "/foo/", "bar"}, 79 {"/foo/", "/", "foo/"}, 80 {"/foo/", "/foo", ""}, 81 {"/foo/", "/foo/", ""}, 82 83 // if prefix is not s's prefix, return s 84 {"", "/", ""}, 85 {"/foo", "/bar", "/foo"}, 86 {"/foo", "/foo/bar", "/foo"}, 87 {"foo", "/foo", "foo"}, 88 {"/foo", "foo", "/foo"}, 89 {"/foo", "/foo/", "/foo"}, 90 } { 91 got := TrimFilePathPrefix(tt.s, tt.prefix) 92 if got == tt.want { 93 t.Logf("TrimFilePathPrefix(%q, %q) = %q", tt.s, tt.prefix, got) 94 } else { 95 t.Errorf("TrimFilePathPrefix(%q, %q) = %q, want %q", tt.s, tt.prefix, got, tt.want) 96 } 97 98 if HasFilePathPrefix(tt.s, tt.prefix) { 99 joined := filepath.Join(tt.prefix, got) 100 if clean := filepath.Clean(tt.s); joined != clean { 101 t.Errorf("filepath.Join(%q, %q) = %q, want %q", tt.prefix, got, joined, clean) 102 } 103 } 104 } 105 } 106 107 func TestTrimFilePathPrefixWindows(t *testing.T) { 108 if runtime.GOOS != "windows" { 109 t.Skipf("test requires Windows file paths") 110 } 111 type testCase struct { 112 s, prefix, want string 113 } 114 for _, tt := range []testCase{ 115 {`\`, ``, `\`}, 116 {`\`, `\`, ``}, 117 {`C:`, `C:`, ``}, 118 {`C:\`, `C:`, `\`}, 119 {`C:\`, `C:\`, ``}, 120 {`C:\foo`, ``, `C:\foo`}, 121 {`C:\foo`, `C:`, `\foo`}, 122 {`C:\foo`, `C:\`, `foo`}, 123 {`C:\foo`, `C:\foo`, ``}, 124 {`C:\foo\`, `C:\foo`, ``}, 125 {`C:\foo\bar`, `C:\foo`, `bar`}, 126 {`C:\foo\bar`, `C:\foo\`, `bar`}, 127 // if prefix is not s's prefix, return s 128 {`C:\foo`, `C:\bar`, `C:\foo`}, 129 {`C:\foo`, `C:\foo\bar`, `C:\foo`}, 130 {`C:`, `C:\`, `C:`}, 131 // if volumes are different, return s 132 {`C:`, ``, `C:`}, 133 {`C:\`, ``, `C:\`}, 134 {`C:\foo`, ``, `C:\foo`}, 135 {`C:\foo`, `\foo`, `C:\foo`}, 136 {`C:\foo`, `D:\foo`, `C:\foo`}, 137 138 //UNC path 139 {`\\host\share\foo`, `\\host\share`, `foo`}, 140 {`\\host\share\foo`, `\\host\share\`, `foo`}, 141 {`\\host\share\foo`, `\\host\share\foo`, ``}, 142 {`\\host\share\foo\bar`, `\\host\share\foo`, `bar`}, 143 {`\\host\share\foo\bar`, `\\host\share\foo\`, `bar`}, 144 // if prefix is not s's prefix, return s 145 {`\\host\share\foo`, `\\host\share\bar`, `\\host\share\foo`}, 146 {`\\host\share\foo`, `\\host\share\foo\bar`, `\\host\share\foo`}, 147 // if either host or share name is different, return s 148 {`\\host\share\foo`, ``, `\\host\share\foo`}, 149 {`\\host\share\foo`, `\foo`, `\\host\share\foo`}, 150 {`\\host\share\foo`, `\\host\other\`, `\\host\share\foo`}, 151 {`\\host\share\foo`, `\\other\share\`, `\\host\share\foo`}, 152 {`\\host\share\foo`, `\\host\`, `\\host\share\foo`}, 153 {`\\host\share\foo`, `\share\`, `\\host\share\foo`}, 154 155 // only volume names are case-insensitive 156 {`C:\foo`, `c:`, `\foo`}, 157 {`C:\foo`, `c:\foo`, ``}, 158 {`c:\foo`, `C:`, `\foo`}, 159 {`c:\foo`, `C:\foo`, ``}, 160 {`C:\foo`, `C:\Foo`, `C:\foo`}, 161 {`\\Host\Share\foo`, `\\host\share`, `foo`}, 162 {`\\Host\Share\foo`, `\\host\share\foo`, ``}, 163 {`\\host\share\foo`, `\\Host\Share`, `foo`}, 164 {`\\host\share\foo`, `\\Host\Share\foo`, ``}, 165 {`\\Host\Share\foo`, `\\Host\Share\Foo`, `\\Host\Share\foo`}, 166 } { 167 got := TrimFilePathPrefix(tt.s, tt.prefix) 168 if got == tt.want { 169 t.Logf("TrimFilePathPrefix(%#q, %#q) = %#q", tt.s, tt.prefix, got) 170 } else { 171 t.Errorf("TrimFilePathPrefix(%#q, %#q) = %#q, want %#q", tt.s, tt.prefix, got, tt.want) 172 } 173 174 if HasFilePathPrefix(tt.s, tt.prefix) { 175 // Although TrimFilePathPrefix is only case-insensitive in the volume name, 176 // what we care about in testing Join is that absolute paths remain 177 // absolute and relative paths remaining relative — there is no harm in 178 // over-normalizing letters in the comparison, so we use EqualFold. 179 joined := filepath.Join(tt.prefix, got) 180 if clean := filepath.Clean(tt.s); !strings.EqualFold(joined, clean) { 181 t.Errorf("filepath.Join(%#q, %#q) = %#q, want %#q", tt.prefix, got, joined, clean) 182 } 183 } 184 } 185 }