package main import ( "context" "encoding/json" "os" "path/filepath" "strings" "testing" "time" ) // hq issue 488: the issue tracker's reserve takes the highest decision and research number from the knowledge base, // which holds every record — reserved, withdrawn and proposed numbers included, since each is spent — rather than // reading hq's folders, which empty when the records leave. func TestTheHighestToolAnswersTheHighestNumberHeldPerKind(t *testing.T) { eachStore(t, func(t *testing.T, s Store) { w := imported(t, s) tool := highestTool(w.k) answer := func() Highest { t.Helper() out, err := tool.Run(map[string]any{}) if err != nil { t.Fatal(err) } raw, _ := json.Marshal(out) var h Highest if err := json.Unmarshal(raw, &h); err != nil { t.Fatal(err) } return h } if h := answer(); h.Decision != 290 || h.Research != 45 || h.Records != 11 { t.Fatalf("%+v", h) } // A number reserved, and later withdrawn, is spent: it is the highest. w.reserved(t, "author@g14") // 300 w.clock = w.clock.Add(DefaultReservedFor + time.Hour) if _, err := w.k.Withdraw(); err != nil { t.Fatal(err) } if h := answer(); h.Decision != 300 || h.Research != 45 { t.Fatalf("after a reservation withdrawn: %+v", h) } if _, err := tool.Run(map[string]any{"kind": "decision"}); err == nil { t.Fatal("an argument it does not take was taken") } }) // A knowledge base that holds nothing answers nothing: a 0 would start a counter at 1. empty := newWorld(t, newMemStore(), fixture()) if _, err := highestTool(empty.k).Run(map[string]any{}); err == nil || !strings.Contains(err.Error(), "holds no record") { t.Fatalf("an empty knowledge base: %v", err) } } // hq issue 488: once the records have left hq, an import at a later commit finds none. It refuses, saying so, // rather than reporting nothing created as a success. func TestTheImportRefusesACommitWhereHqHoldsNoRecords(t *testing.T) { dir := t.TempDir() write := func(path, text string) { t.Helper() if err := writeFileAll(dir+"/"+path, text); err != nil { t.Fatal(err) } } write("COMMIT", "0123456789abcdef0123456789abcdef01234567\n") write("02-DECISIONS/README.md", "# Decisions\n\nThey live in the knowledge base.\n") write("01-RESEARCH/README.md", "# Research\n") w := newWorld(t, newMemStore(), dirRecords{dir: dir}) for _, dry := range []bool{true, false} { out, err := w.k.Import("import@test", ImportAsk{DryRun: dry}, dirRecords{dir: dir}) if err == nil || !strings.Contains(err.Error(), "holds no decision record or research effort") || !strings.Contains(err.Error(), "0123456789ab") { t.Fatalf("dry %v: %+v %v", dry, out, err) } } if all, _ := w.k.Store.All(context.Background()); len(all) != 0 { t.Fatal("written") } } func writeFileAll(path, text string) error { if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { return err } return os.WriteFile(path, []byte(text), 0o644) }