diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 13:26:51 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 13:26:51 +0200 |
| commit | 07c24054cab965800983ef40f53a05c2db131ede (patch) | |
| tree | 741db561d614b35f8f94fee04fb5ce663a629a0b /cmd/krino/review_test.go | |
| parent | 70dccf8d573028aaed64185acb8e134e5339afa3 (diff) | |
| download | krino-07c24054cab965800983ef40f53a05c2db131ede.tar.gz krino-07c24054cab965800983ef40f53a05c2db131ede.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.go | 46 |
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) + } +} |
