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) } }