Modules talk over the bus. The power module's bundle puts each fresh reading of its own sampler in its state draw, keyed by the machine; the bar's block shows that state, which the bar's bundle watches under the read the mesh grants it. A new catalogue check refuses a module naming another module's path under /run or /var/lib.
93 lines
3.0 KiB
Go
93 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
)
|
|
|
|
// Defends novox/hq ADR 0260: a value another module keeps reaches the bar over the bus, through this
|
|
// module's own bundle and directory, and an old one is not shown as if it were now.
|
|
|
|
func TestAValueIsKeptAsItsTextAndGoneWhenDeleted(t *testing.T) {
|
|
dir := t.TempDir()
|
|
w := Wanted{"power.draw", "laptop"}
|
|
if err := keep(dir, w, stdio.StateChange{Op: "put", Value: []byte(`{"text":"18.2 W machine","watts":18.2}`)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
b, err := os.ReadFile(filepath.Join(dir, "power.draw@laptop"))
|
|
if err != nil || string(b) != "18.2 W machine\n" {
|
|
t.Fatalf("%q %v", b, err)
|
|
}
|
|
if err := keep(dir, w, stdio.StateChange{Op: "delete"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "power.draw@laptop")); !os.IsNotExist(err) {
|
|
t.Fatal("a deleted value is still shown")
|
|
}
|
|
if err := keep(dir, w, stdio.StateChange{Op: "put", Value: []byte(`"no text"`)}); err == nil {
|
|
t.Fatal("a value with no text was kept")
|
|
}
|
|
}
|
|
|
|
func TestARefusedWatchIsTriedAgainAndAWatchedOneIsNot(t *testing.T) {
|
|
bar := filepath.Join(t.TempDir(), "bottom-bar.toml")
|
|
if err := os.WriteFile(bar, []byte(`command = "~/.local/bin/i3status-value power.draw laptop"`+"\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
watching := map[Wanted]bool{}
|
|
calls := 0
|
|
refuse := func(string, string, func(stdio.StateChange) error) error { calls++; return errors.New("not granted") }
|
|
if said := followValues([]string{bar}, t.TempDir(), watching, refuse); len(said) != 1 || !strings.Contains(said[0], "not granted") {
|
|
t.Fatalf("%v", said)
|
|
}
|
|
accept := func(state, key string, _ func(stdio.StateChange) error) error {
|
|
calls++
|
|
if state != "power.draw" || key != "laptop" {
|
|
t.Fatalf("watched %s %s", state, key)
|
|
}
|
|
return nil
|
|
}
|
|
followValues([]string{bar}, t.TempDir(), watching, accept)
|
|
followValues([]string{bar}, t.TempDir(), watching, accept)
|
|
if calls != 2 {
|
|
t.Fatalf("%d watches; once refused, once taken, then left alone", calls)
|
|
}
|
|
}
|
|
|
|
func TestTheBlocksCommandShowsOnlyAFreshValue(t *testing.T) {
|
|
runtime := t.TempDir()
|
|
dir := filepath.Join(runtime, "i3status-rust", "values")
|
|
run := func() string {
|
|
cmd := exec.Command("sh", "../../files/bin/i3status-value", "power.draw", "laptop")
|
|
cmd.Env = append(os.Environ(), "XDG_RUNTIME_DIR="+runtime)
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return strings.TrimSpace(string(out))
|
|
}
|
|
if got := run(); got != "" {
|
|
t.Fatalf("no value: %q", got)
|
|
}
|
|
if err := keep(dir, Wanted{"power.draw", "laptop"}, stdio.StateChange{Op: "put", Value: []byte(`{"text":"8.0 W CPU"}`)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := run(); got != "8.0 W CPU" {
|
|
t.Fatalf("fresh: %q", got)
|
|
}
|
|
old := time.Now().Add(-31 * time.Second)
|
|
if err := os.Chtimes(filepath.Join(dir, "power.draw@laptop"), old, old); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := run(); got != "" {
|
|
t.Fatalf("31 s old: %q", got)
|
|
}
|
|
}
|