Files
mesh-catalog/modules/polychromatic/cmd/polychromatic-tools/manifest_test.go
T

143 lines
5.0 KiB
Go

package main
import (
"encoding/json"
"os"
"os/exec"
"path/filepath"
"reflect"
"strings"
"testing"
)
// polychromatic's shape (novox/hq ADR 0205, ADR 0208, ADR 0212): no package (the tray is outside the
// official repositories and kept as found), the X display on its own machine, one contribution to the
// window manager's configuration that is the tray's one start, nothing of the openrazer module's, and
// the Go bundle serving exactly the listed polychromatic_ tools.
type manifest struct {
Module string `json:"module"`
Version string `json:"version"`
Capabilities []string `json:"capabilities"`
Requires []string `json:"requires"`
Tools []string `json:"tools"`
Resources []map[string]any `json:"resources"`
Claims []any `json:"claims"`
Seats []any `json:"seats"`
Shell []any `json:"shell"`
Moved bool `json:"moved"`
Contributions []any `json:"contributions"`
Items []struct {
Collection string `json:"collection"`
Name string `json:"name"`
Template string `json:"template"`
} `json:"items"`
Environment any `json:"environment"`
Build struct {
Artifacts []map[string]any `json:"artifacts"`
} `json:"build"`
}
func readManifest(t *testing.T) (manifest, string) {
t.Helper()
raw, err := os.ReadFile(filepath.Join("..", "..", "module.json"))
if err != nil {
t.Fatal(err)
}
dec := json.NewDecoder(strings.NewReader(string(raw)))
dec.DisallowUnknownFields()
var m manifest
if err := dec.Decode(&m); err != nil {
t.Fatalf("module.json: %v", err)
}
return m, string(raw)
}
func TestTheToolsAgreeWithTheManifest(t *testing.T) {
m, raw := readManifest(t)
served := map[string]bool{}
for _, tool := range tools() {
served[tool.Name] = true
if !strings.HasPrefix(tool.Name, "polychromatic_") || strings.TrimSpace(tool.Description) == "" {
t.Errorf("%s: prefixed %s and described", tool.Name, "polychromatic_")
}
}
for _, name := range m.Tools {
if !served[name] {
t.Errorf("module.json lists %s, which the bundle does not serve", name)
}
delete(served, name)
}
for name := range served {
t.Errorf("the bundle serves %s, which module.json does not list", name)
}
if len(m.Build.Artifacts) != 2 { // the tools bundle and the archive of its template
t.Fatalf("%v", m.Build.Artifacts)
}
b := m.Build.Artifacts[0]
if b["kind"] != "bundle" || b["language"] != "go" || b["system"] != "arch" ||
b["from"] != "cmd/polychromatic-tools" || b["binary"] != "polychromatic-tools" {
t.Errorf("the Go tools bundle: %v", b)
}
s := strings.ToLower(raw)
for _, never := range []string{"/home/", "jochen", "g14", "shanks", "novox.be", "http", "password", "token"} {
if strings.Contains(s, never) {
t.Errorf("module.json names %q", never)
}
}
}
func TestItDeclaresNoPackageAndContributesTheTraysOneStart(t *testing.T) {
m, raw := readManifest(t)
if m.Module != "polychromatic" || !reflect.DeepEqual(m.Requires, []string{"x11-display"}) {
t.Fatalf("%+v", m)
}
if m.Resources != nil || m.Capabilities != nil || m.Claims != nil || m.Seats != nil || m.Environment != nil || m.Shell != nil {
t.Fatal("no package (outside the official repositories), no seat, no environment, no xinitrc start")
}
var code []string
for _, l := range strings.Split(displayLines(t, m), "\n") {
if l = strings.TrimSpace(l); l != "" && !strings.HasPrefix(l, "#") {
code = append(code, l)
}
}
if !reflect.DeepEqual(code, []string{"exec --no-startup-id " + trayWord}) {
t.Fatalf("one line, the tray's start with exec (a reload must not start it again): %q", code)
}
for _, never := range []string{"openrazer", "preferences.json", "autostart\""} {
if strings.Contains(raw, never) {
t.Errorf("module.json names %s", never)
}
}
}
// The window manager's own check parses the line, as the i3 module's catalogue-wide test does with
// every contribution together.
func TestTheContributionParsesInI3(t *testing.T) {
i3, err := exec.LookPath("i3")
if err != nil {
t.Skip("no i3 here to check with")
}
m, _ := readManifest(t)
path := filepath.Join(t.TempDir(), "config")
os.WriteFile(path, []byte("set $mod Mod4\n"+displayLines(t, m)), 0o644)
if out, err := exec.Command(i3, "-C", "-c", path).CombinedOutput(); err != nil || strings.Contains(string(out), "ERROR") {
t.Fatalf("i3 -C: %v %s", err, out)
}
}
// displayLines is the module's lines for the window manager: the text of the template of its one item of the
// collection contribution:node-display-session:config (design 57 L3, issue 848).
func displayLines(t *testing.T, m manifest) string {
t.Helper()
if !m.Moved || len(m.Contributions) != 0 || len(m.Items) != 1 ||
m.Items[0].Collection != "contribution:node-display-session:config" {
t.Fatalf("moved %v, contributions %v, items %+v", m.Moved, m.Contributions, m.Items)
}
text, err := os.ReadFile(filepath.Join("..", "..", m.Items[0].Template))
if err != nil {
t.Fatal(err)
}
return string(text)
}