package main import ( "os" "path/filepath" "reflect" "strings" "testing" ) func module(t *testing.T, root, name, body string) { t.Helper() dir := filepath.Join(root, "modules", name) if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "module.json"), []byte(body), 0o644); err != nil { t.Fatal(err) } } // A file resource that says its text inline is found, by module and resource; one naming its template, a // resource that is not a file and a window-manager addition are not (novox/hq ADR 0349 ยง2). func TestEveryInlineFileTextIsFound(t *testing.T) { root := t.TempDir() module(t, root, "inline", `{"module":"inline","resources":[{"id":"a","type":"file","content":"x"},`+ `{"id":"b","type":"file","template":"files/b"},{"id":"c","type":"file","content":""}]}`) module(t, root, "templated", `{"module":"templated","resources":[{"id":"a","type":"file","template":"files/a"},`+ `{"id":"d","type":"directory","path":"/x"}],"contributions":{"i3":[{"content":"bindsym x"}]}}`) got, err := Check(root) if err != nil { t.Fatal(err) } want := map[string][]string{"inline": {"a", "c"}} if !reflect.DeepEqual(got, want) { t.Fatalf("found %v, want %v", got, want) } } // A module not on the list keeps no file text inline; one on the list that keeps none is taken off it; a line the // trunk's list does not hold is refused, so the list only shrinks until it is empty. func TestTheListOfModulesKeepingTextInlineOnlyShrinks(t *testing.T) { found := map[string][]string{"old": {"a"}, "forgotten": {"b"}} inline := map[string]bool{"old": true, "done": true, "new": true} base := map[string]bool{"old": true, "done": true, "forgotten": true} refused, stale, added := Judge(found, inline, base) if !reflect.DeepEqual(refused, []string{"forgotten"}) || !reflect.DeepEqual(stale, []string{"done", "new"}) || !reflect.DeepEqual(added, []string{"new"}) { t.Fatalf("refused %v, stale %v, added %v", refused, stale, added) } } func TestTheListIsReadWithoutItsComments(t *testing.T) { path := filepath.Join(t.TempDir(), "inline") if err := os.WriteFile(path, []byte("# why\n\npower\n showcase \n"), 0o644); err != nil { t.Fatal(err) } got, err := Listed(path) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(got, map[string]bool{"power": true, "showcase": true}) { t.Fatalf("read %v", got) } } // The catalogue itself: no module keeps a file's text inline but those the list names, and the list names none // that keeps it no longer (design 57 package T5, issue 658: the ten modules without a build moved). func TestTheCatalogueKeepsFileTextInlineOnlyWhereListed(t *testing.T) { found, err := Check("../..") if err != nil { t.Fatal(err) } inline, err := Listed(listFile) if err != nil { t.Fatal(err) } refused, stale, _ := Judge(found, inline, inline) if len(refused) > 0 || len(stale) > 0 { t.Fatalf("keeping file text inline and not listed: %v; listed and keeping none: %v", refused, stale) } } // A refusal names the refused module's own templates directory, not files/ when the module names another (issue 809). func TestARefusalNamesTheModulesOwnTemplatesDirectory(t *testing.T) { root := t.TempDir() module(t, root, "own", `{"module":"own","templates":"t/","resources":[{"id":"a","type":"file","content":"x"}]}`) module(t, root, "plain", `{"module":"plain","resources":[{"id":"a","type":"file","content":"x"}]}`) module(t, root, "bare", `{"module":"bare","templates":"templates","resources":[]}`) for module, dir := range map[string]string{"own": "t/", "plain": "files/", "bare": "templates/"} { if got := TemplatesDir(root, module); got != dir { t.Fatalf("%s: directory %q, want %q", module, got, dir) } } msg := Refusal("own", []string{"a"}, TemplatesDir(root, "own")) if !strings.Contains(msg, "t/") || strings.Contains(msg, "files/") { t.Fatalf("refusal %q", msg) } if msg := Gained("own", TemplatesDir(root, "own")); !strings.Contains(msg, "t/") || strings.Contains(msg, "files/") { t.Fatalf("gained %q", msg) } }