github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/embed/internal/embedtest/embed_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 embedtest 6 7 import ( 8 "embed" 9 "io" 10 "reflect" 11 "testing" 12 "testing/fstest" 13 ) 14 15 //go:embed testdata/h*.txt 16 //go:embed c*.txt testdata/g*.txt 17 var global embed.FS 18 19 //go:embed c*txt 20 var concurrency string 21 22 //go:embed testdata/g*.txt 23 var glass []byte 24 25 func testFiles(t *testing.T, f embed.FS, name, data string) { 26 t.Helper() 27 d, err := f.ReadFile(name) 28 if err != nil { 29 t.Error(err) 30 return 31 } 32 if string(d) != data { 33 t.Errorf("read %v = %q, want %q", name, d, data) 34 } 35 } 36 37 func testString(t *testing.T, s, name, data string) { 38 t.Helper() 39 if s != data { 40 t.Errorf("%v = %q, want %q", name, s, data) 41 } 42 } 43 44 func testDir(t *testing.T, f embed.FS, name string, expect ...string) { 45 t.Helper() 46 dirs, err := f.ReadDir(name) 47 if err != nil { 48 t.Error(err) 49 return 50 } 51 var names []string 52 for _, d := range dirs { 53 name := d.Name() 54 if d.IsDir() { 55 name += "/" 56 } 57 names = append(names, name) 58 } 59 if !reflect.DeepEqual(names, expect) { 60 t.Errorf("readdir %v = %v, want %v", name, names, expect) 61 } 62 } 63 64 // Tests for issue 49514. 65 var _ = '"' 66 var _ = '\'' 67 var _ = '🦆' 68 69 func TestGlobal(t *testing.T) { 70 testFiles(t, global, "concurrency.txt", "Concurrency is not parallelism.\n") 71 testFiles(t, global, "testdata/hello.txt", "hello, world\n") 72 testFiles(t, global, "testdata/glass.txt", "I can eat glass and it doesn't hurt me.\n") 73 74 if err := fstest.TestFS(global, "concurrency.txt", "testdata/hello.txt"); err != nil { 75 t.Fatal(err) 76 } 77 78 testString(t, concurrency, "concurrency", "Concurrency is not parallelism.\n") 79 testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n") 80 } 81 82 //go:embed testdata 83 var testDirAll embed.FS 84 85 func TestDir(t *testing.T) { 86 all := testDirAll 87 testFiles(t, all, "testdata/hello.txt", "hello, world\n") 88 testFiles(t, all, "testdata/i/i18n.txt", "internationalization\n") 89 testFiles(t, all, "testdata/i/j/k/k8s.txt", "kubernetes\n") 90 testFiles(t, all, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n") 91 92 testDir(t, all, ".", "testdata/") 93 testDir(t, all, "testdata/i", "i18n.txt", "j/") 94 testDir(t, all, "testdata/i/j", "k/") 95 testDir(t, all, "testdata/i/j/k", "k8s.txt") 96 } 97 98 var ( 99 //go:embed testdata 100 testHiddenDir embed.FS 101 102 //go:embed testdata/* 103 testHiddenStar embed.FS 104 ) 105 106 func TestHidden(t *testing.T) { 107 dir := testHiddenDir 108 star := testHiddenStar 109 110 t.Logf("//go:embed testdata") 111 112 testDir(t, dir, "testdata", 113 "-not-hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt") 114 115 t.Logf("//go:embed testdata/*") 116 117 testDir(t, star, "testdata", 118 "-not-hidden/", ".hidden/", "_hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt") 119 120 testDir(t, star, "testdata/.hidden", 121 "fortune.txt", "more/") // but not .more or _more 122 } 123 124 func TestUninitialized(t *testing.T) { 125 var uninitialized embed.FS 126 testDir(t, uninitialized, ".") 127 f, err := uninitialized.Open(".") 128 if err != nil { 129 t.Fatal(err) 130 } 131 defer f.Close() 132 fi, err := f.Stat() 133 if err != nil { 134 t.Fatal(err) 135 } 136 if !fi.IsDir() { 137 t.Errorf("in uninitialized embed.FS, . is not a directory") 138 } 139 } 140 141 var ( 142 //go:embed "testdata/hello.txt" 143 helloT []T 144 //go:embed "testdata/hello.txt" 145 helloUint8 []uint8 146 //go:embed "testdata/hello.txt" 147 helloEUint8 []EmbedUint8 148 //go:embed "testdata/hello.txt" 149 helloBytes EmbedBytes 150 //go:embed "testdata/hello.txt" 151 helloString EmbedString 152 ) 153 154 type T byte 155 type EmbedUint8 uint8 156 type EmbedBytes []byte 157 type EmbedString string 158 159 // golang.org/issue/47735 160 func TestAliases(t *testing.T) { 161 all := testDirAll 162 want, e := all.ReadFile("testdata/hello.txt") 163 if e != nil { 164 t.Fatal("ReadFile:", e) 165 } 166 check := func(g any) { 167 got := reflect.ValueOf(g) 168 for i := 0; i < got.Len(); i++ { 169 if byte(got.Index(i).Uint()) != want[i] { 170 t.Fatalf("got %v want %v", got.Bytes(), want) 171 } 172 } 173 } 174 check(helloT) 175 check(helloUint8) 176 check(helloEUint8) 177 check(helloBytes) 178 check(helloString) 179 } 180 181 func TestOffset(t *testing.T) { 182 file, err := testDirAll.Open("testdata/hello.txt") 183 if err != nil { 184 t.Fatal("Open:", err) 185 } 186 187 want := "hello, world\n" 188 189 // Read the entire file. 190 got := make([]byte, len(want)) 191 n, err := file.Read(got) 192 if err != nil { 193 t.Fatal("Read:", err) 194 } 195 if n != len(want) { 196 t.Fatal("Read:", n) 197 } 198 if string(got) != want { 199 t.Fatalf("Read: %q", got) 200 } 201 202 // Try to read one byte; confirm we're at the EOF. 203 var buf [1]byte 204 n, err = file.Read(buf[:]) 205 if err != io.EOF { 206 t.Fatal("Read:", err) 207 } 208 if n != 0 { 209 t.Fatal("Read:", n) 210 } 211 212 // Use seek to get the offset at the EOF. 213 seeker := file.(io.Seeker) 214 off, err := seeker.Seek(0, io.SeekCurrent) 215 if err != nil { 216 t.Fatal("Seek:", err) 217 } 218 if off != int64(len(want)) { 219 t.Fatal("Seek:", off) 220 } 221 222 // Use ReadAt to read the entire file, ignoring the offset. 223 at := file.(io.ReaderAt) 224 got = make([]byte, len(want)) 225 n, err = at.ReadAt(got, 0) 226 if err != nil { 227 t.Fatal("ReadAt:", err) 228 } 229 if n != len(want) { 230 t.Fatalf("ReadAt: got %d bytes, want %d bytes", n, len(want)) 231 } 232 if string(got) != want { 233 t.Fatalf("ReadAt: got %q, want %q", got, want) 234 } 235 236 // Use ReadAt with non-zero offset. 237 off = int64(7) 238 want = want[off:] 239 got = make([]byte, len(want)) 240 n, err = at.ReadAt(got, off) 241 if err != nil { 242 t.Fatal("ReadAt:", err) 243 } 244 if n != len(want) { 245 t.Fatalf("ReadAt: got %d bytes, want %d bytes", n, len(want)) 246 } 247 if string(got) != want { 248 t.Fatalf("ReadAt: got %q, want %q", got, want) 249 } 250 }