summaryrefslogtreecommitdiff
path: root/cmd/krino/review_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 13:26:51 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 13:26:51 +0200
commit07c24054cab965800983ef40f53a05c2db131ede (patch)
tree741db561d614b35f8f94fee04fb5ce663a629a0b /cmd/krino/review_test.go
parent70dccf8d573028aaed64185acb8e134e5339afa3 (diff)
downloadkrino-0.0.3.tar.gz
krino-0.0.3.zip
krino: 0.0.3 — the plan as one block per file, wrapped, and -Pv0.0.3
Each file shows its steps, then the rule and the reason it matched, one field per line; on a terminal every line wraps to its width with continuation lines under their own column, and piped output is never wrapped. Choosing per file shows the same block. -P / --no-pager prints the plan without the pager. A duplicate's original is shown with ~.
Diffstat (limited to 'cmd/krino/review_test.go')
-rw-r--r--cmd/krino/review_test.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/cmd/krino/review_test.go b/cmd/krino/review_test.go
index 6bf5ea7..a387022 100644
--- a/cmd/krino/review_test.go
+++ b/cmd/krino/review_test.go
@@ -3,8 +3,10 @@
package main
import (
+ "io"
"strings"
"testing"
+ "unicode/utf8"
"krino/internal/plan"
"krino/internal/scan"
@@ -124,3 +126,47 @@ func TestPerFileDestinationIsRootRelative(t *testing.T) {
t.Errorf("destination outside root should be ~-abbreviated:\n%s", text)
}
}
+
+// TestPerFileShowsTheWholeBlock: choosing per file shows each step, its
+// rule and its reason: the same block the plan shows, not the steps alone.
+func TestPerFileShowsTheWholeBlock(t *testing.T) {
+ cs := []plan.Chain{{File: scan.File{Rel: "a.pdf"}, Steps: []plan.Step{
+ {Kind: plan.Move, Rule: "acme", Dst: "/w/a.pdf", Reason: `content "acme ltd"`},
+ }}}
+ out := new(strings.Builder)
+ if _, _, err := reviewChains(strings.NewReader("cy"), out, cs, "", palette{}); err != nil {
+ t.Fatal(err)
+ }
+ want := "\n[1/1] a.pdf\n move → /w/\n rule acme\n because content \"acme ltd\"\n"
+ if !strings.Contains(out.String(), want) {
+ t.Errorf("per-file prompt:\n%s\nwant substring:\n%s", out, want)
+ }
+}
+
+// TestPerFileWrapsToTheTerminal: on a narrow terminal the per-file block
+// and its key prompt both fit, and the prompt's pieces read back as the
+// whole prompt.
+func TestPerFileWrapsToTheTerminal(t *testing.T) {
+ old := widthPolicy
+ t.Cleanup(func() { widthPolicy = old })
+ widthPolicy = func(io.Writer) int { return 60 }
+ cs := []plan.Chain{{File: scan.File{Rel: "a.pdf"}, Steps: []plan.Step{
+ {Kind: plan.Move, Rule: "acme", Dst: "/w/some/deeply/nested/destination/directory/for/invoices/a.pdf", Reason: `content "acme ltd"`},
+ }}}
+ out := new(strings.Builder)
+ if _, _, err := reviewChains(strings.NewReader("cy"), out, cs, "", palette{}); err != nil {
+ t.Fatal(err)
+ }
+ var prompt string
+ for _, l := range strings.Split(out.String(), "\n") {
+ if n := utf8.RuneCountInString(l); n > 60 {
+ t.Errorf("line of %d runes exceeds width 60: %q", n, l)
+ }
+ if strings.HasPrefix(l, " [y] yes") || (prompt != "" && strings.HasPrefix(l, " ") && !strings.HasPrefix(l, " ")) {
+ prompt += strings.TrimPrefix(l, " ")
+ }
+ }
+ if prompt != perFileKeys {
+ t.Errorf("wrapped prompt reads %q, want %q\n%s", prompt, perFileKeys, out)
+ }
+}