rastrillo / abono Public

Clone
git clone https://amadan.net/rastrillo/abono

Plain git — no account needed to clone.

Download

Download this file

1package main
2
3import (
4 "io/fs"
5 "net/http"
6 "os"
7 "path"
8 "strings"
9 "testing"
10
11 "amadan.net/rastrillo/abono"
12)
13
14// exampleKeys is every "example.*" key the example's own templates and Go
15// name. The generated pages (abono_pages.go, templates/abono/) are abono's
16// and use abono.* keys, which its own gate holds to its catalog; main.go
17// is configuration, where "example.db" is a file name, not a key.
18func exampleKeys(t *testing.T) map[string]bool {
19 t.Helper()
20 used := map[string]bool{}
21 root := os.DirFS(".")
22 err := fs.WalkDir(root, ".", func(p string, d fs.DirEntry, err error) error {
23 if err != nil {
24 return err
25 }
26 if d.IsDir() {
27 if p == "templates/abono" || p == "migrations" {
28 return fs.SkipDir
29 }
30 return nil
31 }
32 if ext := path.Ext(p); (ext != ".html" && ext != ".go") || strings.HasSuffix(p, "_test.go") || p == "abono_pages.go" || p == "main.go" {
33 return nil
34 }
35 src, err := fs.ReadFile(root, p)
36 if err != nil {
37 return err
38 }
39 for _, m := range keyLiteral.FindAllSubmatch(src, -1) {
40 if k := string(m[1]); strings.HasPrefix(k, "example.") {
41 used[k] = true
42 }
43 }
44 return nil
45 })
46 if err != nil {
47 t.Fatal(err)
48 }
49 return used
50}
51
52// The example's "example.*" keys and locales/en.toml agree: every key its
53// templates use is defined there, every key there is used, and the file
54// holds nothing but example.* keys (abono's belong to abono's catalog).
55func TestExampleCatalogCoversTheKeysTheExampleUses(t *testing.T) {
56 own, err := ownCatalog()
57 if err != nil {
58 t.Fatal(err)
59 }
60 used := exampleKeys(t)
61 if !used["example.signout"] {
62 t.Error("exampleKeys misses example.signout, which the layout uses")
63 }
64 for k := range used {
65 if _, ok := own[k]; !ok {
66 t.Errorf("%s is used but not in locales/en.toml", k)
67 }
68 }
69 for k := range own {
70 if !used[k] {
71 t.Errorf("%s is in locales/en.toml but nothing uses it", k)
72 }
73 if !strings.HasPrefix(k, "example.") {
74 t.Errorf("%s is in the example's catalog but is not an example.* key", k)
75 }
76 }
77 for k := range abono.Catalog() {
78 if strings.HasPrefix(k, "example.") {
79 t.Errorf("abono's catalog has %s, which is the example's", k)
80 }
81 }
82 merged := Catalog()
83 for k, v := range abono.Catalog() {
84 if merged[k] != v {
85 t.Errorf("Catalog() changed abono's %s", k)
86 }
87 }
88 for k, v := range own {
89 if merged[k] != v {
90 t.Errorf("Catalog() lacks the example's %s", k)
91 }
92 }
93}
94
95// With no catalog given, the example runs on its own: a signed-in page
96// says "Sign out", not the key.
97func TestExampleSaysSignOutInItsOwnCatalog(t *testing.T) {
98 app := newApp(t, func(c *Config) { c.Catalog = nil })
99 reader := newClient(t, app)
100 reader.signin("reader@example.com")
101 status, body := reader.get("/subscribe")
102 if status != http.StatusOK {
103 t.Fatalf("GET /subscribe: %d", status)
104 }
105 if !strings.Contains(body, ">Sign out<") || strings.Contains(body, "example.signout") {
106 t.Errorf("the nav does not say Sign out:\n%s", body)
107 }
108}
109