Files
mesh-catalog/modules/jetbrains-toolbox/cmd/toolbox-tools/manifest_test.go
T
jochen 75f25fca21 Add slack and jetbrains-toolbox: one start each, the apps kept as found
Slack comes from the AUR and Toolbox from JetBrains' self-updating tarball,
so neither is declared: the host installs official packages only, and a
pinned archive would fight Toolbox's own updates. Slack's start and the
operator's i3 window rules become one node-display-session contribution,
because Slack's own launch-on-login is a symlink in ~/.config/autostart.
Toolbox keeps its own autostart entry as its one start. The shared
desktop.go header now names all four bundles.
2026-10-05 15:05:55 +02:00

97 lines
3.2 KiB
Go

package main
import (
"encoding/json"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
)
// jetbrains-toolbox's shape (novox/hq ADR 0205, ADR 0208, ADR 0182): Toolbox is kept as found, so no
// package, no archive, no file and no start of the module's own (Toolbox writes its own autostart
// entry); the X display on its own machine; and the Go bundle serving exactly the listed toolbox_ 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"`
Contributions []any `json:"contributions"`
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 TestItKeepsToolboxAsFound(t *testing.T) {
m, _ := readManifest(t)
if m.Module != "jetbrains-toolbox" || !reflect.DeepEqual(m.Requires, []string{"x11-display"}) {
t.Fatalf("%+v", m)
}
// Toolbox replaces its own files when it updates itself: a package, an archive or a file of the
// module's in its directory would be a second writer.
if m.Resources != nil || m.Capabilities != nil {
t.Fatalf("no package, no archive, no file: %v %v", m.Resources, m.Capabilities)
}
// Its own autostart entry is its one start: a contribution or a session slot would be a second.
if m.Claims != nil || m.Seats != nil || m.Environment != nil || m.Shell != nil || m.Contributions != nil {
t.Fatal("it holds no seat, sets no environment and adds no start")
}
}
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, "toolbox_") || strings.TrimSpace(tool.Description) == "" {
t.Errorf("%s: prefixed toolbox_ and described", tool.Name)
}
}
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) != 1 {
t.Fatalf("%v", m.Build.Artifacts)
}
b := m.Build.Artifacts[0]
if b["kind"] != "bundle" || b["language"] != "go" || b["system"] != "arch" ||
b["from"] != "cmd/toolbox-tools" || b["binary"] != "toolbox-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)
}
}
}