aboutsummaryrefslogtreecommitdiff
path: root/cmd/krino/matching_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/krino/matching_test.go')
-rw-r--r--cmd/krino/matching_test.go50
1 files changed, 39 insertions, 11 deletions
diff --git a/cmd/krino/matching_test.go b/cmd/krino/matching_test.go
index eaf9494..614edc2 100644
--- a/cmd/krino/matching_test.go
+++ b/cmd/krino/matching_test.go
@@ -4,6 +4,7 @@ package main
import (
"bytes"
+ "encoding/json"
"os"
"path/filepath"
"strings"
@@ -61,12 +62,12 @@ func TestDryRun(t *testing.T) {
t.Fatalf("exit %d: %s", code, errOut)
}
for _, want := range []string{
- "krino: dl ~/dl\n8 scanned · 4 matched · 2 warnings · ",
- "\n inv1.txt acme: type txt, content \"acme ltd\"\n",
- "\n notes.txt rest: not matched, type txt\n",
- "\n report (1).pdf dups: duplicate of report.pdf\n",
+ "krino: dl ~/dl\n8 scanned · 4 to act on · 2 warnings · ",
+ "\n 1 inv1.txt move → Work/Acme/ acme type txt, content \"acme ltd\"\n",
+ "\n 2 notes.txt move → Other/ rest not matched, type txt\n",
+ "\n 4 report (1).pdf trash dups duplicate of report.pdf\n",
"\nwarnings\n brochure.doc acme: content unreadable: needs antiword or catdoc, not installed\n",
- "\nnot matched: 2 · ignored: 1 · busy: 1 (-v lists them)\n",
+ "\nnot acted on: 1 ignored · 1 busy · 2 unmatched (-v lists them)\n",
} {
if !strings.Contains(out, want) {
t.Errorf("output lacks %q:\n%s", want, out)
@@ -74,11 +75,38 @@ func TestDryRun(t *testing.T) {
}
}
+// TestDryRunJSON is the --json counterpart of TestDryRun: with -n it now
+// prints the plan instead of refusing, and the document parses.
+func TestDryRunJSON(t *testing.T) {
+ matchingFixture(t)
+ code, out, errOut := runCLI(t, "-n", "--json")
+ if code != 0 {
+ t.Fatalf("exit %d: %s", code, errOut)
+ }
+ for _, want := range []string{`"action": "move"`, `"rel": "inv1.txt"`} {
+ if !strings.Contains(out, want) {
+ t.Errorf("json output lacks %s:\n%s", want, out)
+ }
+ }
+ var doc struct {
+ Version int `json:"version"`
+ Dirs []struct {
+ Name string `json:"name"`
+ } `json:"dirs"`
+ }
+ if err := json.Unmarshal([]byte(out), &doc); err != nil {
+ t.Fatalf("output does not parse as JSON: %v\n%s", err, out)
+ }
+ if doc.Version != 1 || len(doc.Dirs) != 1 || doc.Dirs[0].Name != "dl" {
+ t.Errorf("document = %+v", doc)
+ }
+}
+
func TestDryRunVerbose(t *testing.T) {
matchingFixture(t)
_, out, _ := runCLI(t, "-n", "-v")
for _, want := range []string{
- "not matched: 2 · ignored: 1 · busy: 1\n",
+ "not acted on: 1 ignored · 1 busy · 2 unmatched\n",
"\nnot matched\n brochure.doc\n report.pdf\n",
"\nskipped\n movie.mkv busy\n movie.mkv.part ignored\n",
} {
@@ -121,7 +149,7 @@ func TestSortFlags(t *testing.T) {
}{
{[]string{"-y", "-n"}, "-y and -n cannot be used together"},
{nil, "applying files is not implemented yet; use -n to see what would happen"},
- {[]string{"-n", "--json"}, "--json is not implemented yet"},
+ {[]string{"--json"}, "--json is not implemented yet"}, // --json without -n stays an error
}
for _, tt := range tests {
if code, _, errOut := runCLI(t, tt.args...); code != 2 || !strings.Contains(errOut, tt.want) {
@@ -355,7 +383,7 @@ func TestLongNameNotPaddedLayoutIntact(t *testing.T) {
conf := `
(path "~/dl")
(min-age 0s)
-(rule "r" (when (type txt)) (stop))
+(rule "r" (when (type txt)) (move "Other"))
`
if err := os.WriteFile(filepath.Join(h, ".config/krino/dirs/dl.conf"), []byte(conf), 0o644); err != nil {
t.Fatal(err)
@@ -365,10 +393,10 @@ func TestLongNameNotPaddedLayoutIntact(t *testing.T) {
if code != 0 {
t.Fatalf("exit %d: %s", code, errOut)
}
- if want := "\n " + long + " r: type txt\n"; !strings.Contains(out, want) {
- t.Errorf("long name should be unpadded (exactly two trailing spaces before the rule column):\n%s\nwant substring:\n%s", out, want)
+ if want := "\n 1 " + long + " move → Other/ r type txt\n"; !strings.Contains(out, want) {
+ t.Errorf("long name should be unpadded (exactly two trailing spaces before the actions column):\n%s\nwant substring:\n%s", out, want)
}
- if want := "\n " + short + strings.Repeat(" ", 40-len(short)) + " r: type txt\n"; !strings.Contains(out, want) {
+ if want := "\n 2 " + short + strings.Repeat(" ", 40-len(short)) + " move → Other/ r type txt\n"; !strings.Contains(out, want) {
t.Errorf("short name should still be padded to the 40-column cap:\n%s\nwant substring:\n%s", out, want)
}
}