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
|
package main
// Run with (the tool is not a workspace module; it is built only by Nix):
//
// cd nix/buildGo/mkembedcfg && GOWORK=off go test main.go main_test.go
import (
"reflect"
"strings"
"testing"
"testing/fstest"
)
// tree mirrors the shapes the old guesser got wrong: a directory pattern with
// a nested subdirectory, hidden and underscore files, and a nested module.
func tree() fstest.MapFS {
f := func(s string) *fstest.MapFile { return &fstest.MapFile{Data: []byte(s)} }
return fstest.MapFS{
"main.go": f("package main"),
"static/a.css": f("a"),
"static/sub/b.js": f("b"),
"static/.hidden": f("h"),
"static/_draft.css": f("d"),
"static/.git/config": f("g"),
"static/nested/go.mod": f("module n"),
"static/nested/x.txt": f("x"),
"templates/i.html": f("i"),
"templates/j.html": f("j"),
"templates/k.txt": f("k"),
"empty/.only-hidden": f("e"),
}
}
func TestResolve(t *testing.T) {
cases := []struct {
pattern string
want []string
}{
// The old guesser matched static/* only and dropped static/sub/b.js.
{"static", []string{"static/a.css", "static/sub/b.js"}},
// all: keeps hidden and underscore names, still stops at a module.
{"all:static", []string{"static/.git/config", "static/.hidden", "static/_draft.css", "static/a.css", "static/sub/b.js"}},
{"templates/*.html", []string{"templates/i.html", "templates/j.html"}},
{"templates/i.html", []string{"templates/i.html"}},
// A hidden file named explicitly is embedded, as with go build.
{"static/.hidden", []string{"static/.hidden"}},
}
for _, c := range cases {
cfg, err := resolve(tree(), "/src", []string{c.pattern})
if err != nil {
t.Errorf("%s: %v", c.pattern, err)
continue
}
if got := cfg.Patterns[c.pattern]; !reflect.DeepEqual(got, c.want) {
t.Errorf("%s = %v, want %v", c.pattern, got, c.want)
}
for _, f := range c.want {
if cfg.Files[f] != "/src/"+f {
t.Errorf("%s: Files[%s] = %q, want /src/%s", c.pattern, f, cfg.Files[f], f)
}
}
}
}
// TestResolveErrors pins that a pattern embedding nothing fails, where the
// old tool mapped it to every embedded file and built successfully.
func TestResolveErrors(t *testing.T) {
cases := map[string]string{
"templates/*.htm": "no matching files",
"missing": "no matching files",
"empty": "contains no embeddable files",
".": "invalid pattern",
"../escape": "invalid pattern",
}
for pattern, want := range cases {
_, err := resolve(tree(), "/src", []string{pattern})
if err == nil || !strings.Contains(err.Error(), want) {
t.Errorf("%s: err = %v, want containing %q", pattern, err, want)
}
}
}
// TestResolveUnion checks Files is the union over patterns, as go build's is.
func TestResolveUnion(t *testing.T) {
cfg, err := resolve(tree(), "/src", []string{"templates/*.html", "templates/i.html", "static"})
if err != nil {
t.Fatal(err)
}
if len(cfg.Files) != 4 {
t.Errorf("Files has %d entries, want 4: %v", len(cfg.Files), cfg.Files)
}
}
|