summaryrefslogtreecommitdiff
path: root/tests/functional/pick-roundtrip/remembering.go
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-06-12 09:19:28 -0300
committerEuAndreh <eu@euandre.org>2026-06-12 09:19:28 -0300
commit46fd0362bce11d709e5efe6d540358533985d363 (patch)
treef77d2ed33c4f3fb6e85353e436efca4e19028f73 /tests/functional/pick-roundtrip/remembering.go
parentrm .tdrc COPYING (diff)
downloadremembering-46fd0362bce11d709e5efe6d540358533985d363.tar.gz
remembering-46fd0362bce11d709e5efe6d540358533985d363.tar.xz
Rewrite remembering in Go
The shell pipeline (sed | sort | tee | awk | sort | cut | "$@" plus the cut | uniq | awk profile rewrite) becomes a single static binary with the same observable behaviour, pinned by the original ranking.sh, signals.sh and cli-opts.sh suites, now aimed at remembering.bin: - the profile keeps the exact on-disk format, COUNT profile TEXT, byte-sorted with new picks appended at 1 and offered-but-never- picked entries persisted at 0; - the menu stays count-descending with byte-order ties, stdin alone defines what is offered, and duplicate profile lines sum for ranking but collapse to the highest count on rewrite, as sort | uniq -f1 did; - the wrapped command's exit status is forwarded as-is (128+sig for signal deaths), its stderr passes through, and an empty pick learns nothing; - the profile rewrite stays atomic via .tmp plus rename. Per the house CLI conventions, -h/-V/--help/--version are gone (the manpage is the documentation; bad options print the usage on stderr and exit 2), and getopts-style attached option arguments (-pNAME) are not accepted any more --- no script in the wild used them. The project layout follows rot: raw go tool compile/link Makefile, mkdeps.sh-generated deps.mk, white-box unit suite, fuzz target over the profile parse/serialize roundtrip, functional pick roundtrip, a 1M-line ranking benchmark, and a single English asciidoc manpage absorbing the old .5 page; the po4a/aux release machinery goes away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'tests/functional/pick-roundtrip/remembering.go')
-rw-r--r--tests/functional/pick-roundtrip/remembering.go129
1 files changed, 129 insertions, 0 deletions
diff --git a/tests/functional/pick-roundtrip/remembering.go b/tests/functional/pick-roundtrip/remembering.go
new file mode 100644
index 0000000..e2d54da
--- /dev/null
+++ b/tests/functional/pick-roundtrip/remembering.go
@@ -0,0 +1,129 @@
+package remembering
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+ "strings"
+)
+
+
+
+func showColour() bool {
+ return os.Getenv("NO_COLOUR") == ""
+}
+
+func testing(message string, body func()) {
+ if showColour() {
+ fmt.Fprintf(
+ os.Stderr,
+ "\033[0;33mtesting\033[0m: %s... ",
+ message,
+ )
+ body()
+ fmt.Fprintf(os.Stderr, "\033[0;32mOK\033[0m.\n")
+ } else {
+ fmt.Fprintf(os.Stderr, "testing: %s... ", message)
+ body()
+ fmt.Fprintf(os.Stderr, "OK.\n")
+ }
+}
+
+func assertEq(given any, expected any) {
+ if !reflect.DeepEqual(given, expected) {
+ if showColour() {
+ fmt.Fprintf(os.Stderr, "\033[0;31mERR\033[0m.\n")
+ } else {
+ fmt.Fprintf(os.Stderr, "ERR.\n")
+ }
+ fmt.Fprintf(os.Stderr, "given != expected\n")
+ fmt.Fprintf(os.Stderr, "given: %#v\n", given)
+ fmt.Fprintf(os.Stderr, "expected: %#v\n", expected)
+ os.Exit(1)
+ }
+}
+
+
+
+func pick(menu string, command ...string) (int, string, string) {
+ out := strings.Builder{}
+ errW := strings.Builder{}
+ rc := run(envT{
+ allArgs: append(
+ []string{"remembering", "-p", "func", "--"},
+ command...,
+ ),
+ in: strings.NewReader(menu),
+ out: &out,
+ err: &errW,
+ })
+ return rc, out.String(), errW.String()
+}
+
+func profileBytes() string {
+ path, err := profilePath("func")
+ if err != nil {
+ panic(err)
+ }
+ data, err := os.ReadFile(path)
+ if err != nil {
+ panic(err)
+ }
+ return string(data)
+}
+
+
+
+func MainTest() {
+ testing("a session of picks shapes the ranking", func() {
+ tmp, err := os.MkdirTemp(
+ "", "remembering-functional-",
+ )
+ assertEq(err, nil)
+ defer os.RemoveAll(tmp)
+ saved := os.Getenv("XDG_DATA_HOME")
+ os.Setenv("XDG_DATA_HOME", tmp)
+ defer os.Setenv("XDG_DATA_HOME", saved)
+
+ menu := "a\nb\nc\nd\ne\n"
+
+ rc, out, errW := pick(menu, "grep", "-F", "c")
+ assertEq(rc, 0)
+ assertEq(out, "c\n")
+ assertEq(errW, "")
+ assertEq(
+ profileBytes(),
+ "0 profile a\n"+
+ "0 profile b\n"+
+ "1 profile c\n"+
+ "0 profile d\n"+
+ "0 profile e\n",
+ )
+
+ // the learnt pick now ranks first
+ rc, out, errW = pick(menu, "head", "-n1")
+ assertEq(rc, 0)
+ assertEq(out, "c\n")
+ assertEq(errW, "")
+ assertEq(
+ profileBytes(),
+ "0 profile a\n"+
+ "0 profile b\n"+
+ "2 profile c\n"+
+ "0 profile d\n"+
+ "0 profile e\n",
+ )
+
+ // a cancelled menu forwards the status and
+ // learns nothing
+ rc, out, _ = pick(menu, "sh", "-c", "exit 3")
+ assertEq(rc, 3)
+ assertEq(out, "")
+ assertEq(
+ strings.Contains(
+ profileBytes(), "2 profile c",
+ ),
+ true,
+ )
+ })
+}