diff options
Diffstat (limited to 'cmd/krino/matching_test.go')
| -rw-r--r-- | cmd/krino/matching_test.go | 50 |
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) } } |
