summaryrefslogtreecommitdiff
path: root/cmd/krino/colour_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/colour_test.go
parent70dccf8d573028aaed64185acb8e134e5339afa3 (diff)
downloadkrino-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/colour_test.go')
-rw-r--r--cmd/krino/colour_test.go88
1 files changed, 59 insertions, 29 deletions
diff --git a/cmd/krino/colour_test.go b/cmd/krino/colour_test.go
index fa014e6..64dbb24 100644
--- a/cmd/krino/colour_test.go
+++ b/cmd/krino/colour_test.go
@@ -7,7 +7,9 @@ import (
"strings"
"testing"
+ "krino/internal/engine"
"krino/internal/plan"
+ "krino/internal/scan"
)
func TestPaletteZeroValueIsPlain(t *testing.T) {
@@ -41,16 +43,6 @@ func TestPaletteStylesWithAnsiSlotsOnly(t *testing.T) {
}
}
-func TestPadStyledPadsOnPlainWidth(t *testing.T) {
- p := palette{on: true}
- if got, want := padStyled("ab", 5, p.rule), "\x1b[34mab\x1b[0m "; got != want {
- t.Errorf("got %q, want %q", got, want)
- }
- if got := padStyled("abcdef", 3, p.rule); got != "\x1b[34mabcdef\x1b[0m" {
- t.Errorf("over-wide cell = %q", got)
- }
-}
-
func TestColourOnHonoursNoColorFlag(t *testing.T) {
old := colourPolicy
t.Cleanup(func() { colourPolicy = old })
@@ -80,34 +72,38 @@ func TestNoColorFlagBeforeAndAfterSubcommand(t *testing.T) {
}
}
-// TestPlanTableColouredAndAligned: with colour on, each element of the
-// action table carries its style, and stripping the escapes gives exactly
-// the plain rendering, so the columns line up.
-func TestPlanTableColouredAndAligned(t *testing.T) {
- root := "/r"
- rows := []planRow{
- {num: "1", file: "a.pdf", step: plan.Step{Kind: plan.Move, Rule: "acme", Dst: "/r/Work/a.pdf", Reason: "type pdf"}},
- {step: plan.Step{Kind: plan.Trash, Rule: "old", Skip: "a duplicate is never deleted", Reason: "matched"}},
- {num: "2", file: "setup.deb", step: plan.Step{Kind: plan.DeletePermanent, Rule: "pkgs", Reason: "age > 90d"}},
- }
- for i := range rows {
- rows[i].actions = actionCell(rows[i].step, root)
- rows[i].rule = rows[i].step.Rule
- rows[i].reason = rows[i].step.Reason
+// TestPlanBlocksColouredAndAligned: with colour on, each element of a
+// block carries its style, a wrapped value keeps its style on every piece,
+// and stripping the escapes gives exactly the plain rendering, so the
+// labels and the wrapping line up with colour on.
+func TestPlanBlocksColouredAndAligned(t *testing.T) {
+ home(t)
+ dp := &engine.DirPlan{
+ Dir: &engine.Dir{Name: "dl", Root: "/r"},
+ Chains: []plan.Chain{
+ {File: scan.File{Rel: "a.pdf"}, Steps: []plan.Step{
+ {Kind: plan.Move, Rule: "acme", Src: "/r/a.pdf", Dst: "/r/Work/a.pdf", Reason: "type pdf"},
+ {Kind: plan.Trash, Rule: "old", Src: "/r/Work/a.pdf", Skip: "a duplicate is never deleted", Reason: "matched"},
+ }},
+ {File: scan.File{Rel: "setup.deb"}, Steps: []plan.Step{
+ {Kind: plan.DeletePermanent, Rule: "pkgs", Src: "/r/setup.deb", Reason: "age > 90d"},
+ }},
+ },
+ Result: &engine.Result{Matched: []engine.FileMatch{{File: scan.File{Rel: "a.pdf"}}, {File: scan.File{Rel: "setup.deb"}}}},
}
var plain, coloured strings.Builder
- printPlanTable(&plain, rows, palette{})
- printPlanTable(&coloured, rows, palette{on: true})
+ printPlan(&plain, dp, false, palette{}, 30)
+ printPlan(&coloured, dp, false, palette{on: true}, 30)
for _, want := range []string{
"\x1b[32mmove\x1b[0m", "\x1b[34macme\x1b[0m", "\x1b[2mtype pdf\x1b[0m",
- "\x1b[2mtrash ", "\x1b[1;31mDELETE permanently\x1b[0m",
+ "\x1b[2mtrash\x1b[0m", "\x1b[2mskipped: ", "\x1b[1;31mDELETE permanently\x1b[0m",
} {
if !strings.Contains(coloured.String(), want) {
- t.Errorf("coloured table lacks %q:\n%q", want, coloured.String())
+ t.Errorf("coloured plan lacks %q:\n%q", want, coloured.String())
}
}
if got := stripSGR(coloured.String()); got != plain.String() {
- t.Errorf("stripped coloured table differs from plain:\n%s\nvs\n%s", got, plain.String())
+ t.Errorf("stripped coloured plan differs from plain:\n%s\nvs\n%s", got, plain.String())
}
}
@@ -162,3 +158,37 @@ func TestDryRunColouredAndNoColor(t *testing.T) {
}
}
}
+
+// TestNoPagerFlagBypassesThePager: with -P or --no-pager, in either
+// position, the plan is written straight out and never handed to the
+// pager; without it, the pager gets it.
+func TestNoPagerFlagBypassesThePager(t *testing.T) {
+ matchingFixture(t)
+ old := pager
+ t.Cleanup(func() { pager = old })
+ paged := 0
+ pager = func(w io.Writer, text string) error {
+ paged++
+ _, err := io.WriteString(w, text)
+ return err
+ }
+ if _, out, _ := runCLI(t, "-n"); paged != 1 || !strings.Contains(out, "report (1).pdf") {
+ t.Errorf("without -P: paged %d times, want 1", paged)
+ }
+ for _, args := range [][]string{{"-P", "-n"}, {"--no-pager", "-n"}, {"-n", "-P"}} {
+ paged = 0
+ _, out, errOut := runCLI(t, args...)
+ if paged != 0 {
+ t.Errorf("%v went through the pager", args)
+ }
+ if !strings.Contains(out, "report (1).pdf") {
+ t.Errorf("%v printed no plan:\n%s\n%s", args, out, errOut)
+ }
+ }
+ if code, _, errOut := runCLI(t, "log", "-P"); code != 0 {
+ t.Errorf("log -P: exit %d: %s", code, errOut)
+ }
+ if !strings.Contains(usage, "--no-pager") {
+ t.Error("usage does not mention --no-pager")
+ }
+}