aboutsummaryrefslogtreecommitdiff
path: root/cmd/krino/commands_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-11 14:47:10 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-11 15:01:57 +0200
commit42b02c47be9b285099203e44a2570636d4ca6f03 (patch)
tree82bcb9e19bd886f36e1ca7b2d94a204c988f1fd1 /cmd/krino/commands_test.go
downloadkrino-42b02c47be9b285099203e44a2570636d4ca6f03.tar.gz
krino-42b02c47be9b285099203e44a2570636d4ca6f03.zip
krino: foundation — sexp reader, config language, init/new/check
Diffstat (limited to 'cmd/krino/commands_test.go')
-rw-r--r--cmd/krino/commands_test.go105
1 files changed, 105 insertions, 0 deletions
diff --git a/cmd/krino/commands_test.go b/cmd/krino/commands_test.go
new file mode 100644
index 0000000..68a2174
--- /dev/null
+++ b/cmd/krino/commands_test.go
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package main
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+// home gives each test its own HOME with an empty XDG config.
+func home(t *testing.T) string {
+ t.Helper()
+ h := t.TempDir()
+ t.Setenv("HOME", h)
+ t.Setenv("XDG_CONFIG_HOME", "")
+ return h
+}
+
+func TestInitNewCheck(t *testing.T) {
+ h := home(t)
+ if err := os.Mkdir(filepath.Join(h, "dl"), 0o755); err != nil {
+ t.Fatal(err)
+ }
+ code, out, errOut := runCLI(t, "init")
+ if code != 0 || !strings.Contains(out, "created ~/.config/krino/krino.conf") {
+ t.Fatalf("init: %d %q %q", code, out, errOut)
+ }
+ code, out, _ = runCLI(t, "check")
+ if code != 0 || !strings.Contains(out, "no directories included") {
+ t.Fatalf("check, empty: %d %q", code, out)
+ }
+ code, out, errOut = runCLI(t, "new", "dl", "~/dl")
+ if code != 0 || !strings.Contains(out, "created ~/.config/krino/dirs/dl.conf") {
+ t.Fatalf("new: %d %q %q", code, out, errOut)
+ }
+ conf := filepath.Join(h, ".config", "krino", "dirs", "dl.conf")
+ rules := "(path \"~/dl\")\n(rule \"pdfs\" (when (type pdf)) (move \"PDF\") (stop))\n"
+ if err := os.WriteFile(conf, []byte(rules), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ code, out, errOut = runCLI(t, "check")
+ if code != 0 || !strings.Contains(out, "dl ~/dl") || !strings.Contains(out, "pdfs") ||
+ !strings.Contains(out, "move PDF, stop") {
+ t.Fatalf("check: %d %q %q", code, out, errOut)
+ }
+ if err := os.WriteFile(conf, []byte(`(path "~/dl") (rule "x" (move PDF))`), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ code, _, errOut = runCLI(t, "check")
+ want := `~/.config/krino/dirs/dl.conf:1:31: rule "x": move takes a string: write (move "PDF")`
+ if code != 2 || !strings.Contains(errOut, want) || !strings.Contains(errOut, "1 problem found") {
+ t.Fatalf("check, broken: %d %q", code, errOut)
+ }
+}
+
+// TestConfigFlagExpandsTilde is item B: -c=~/... is not expanded by the
+// shell (the ~ comes after =), so krino must expand it itself.
+func TestConfigFlagExpandsTilde(t *testing.T) {
+ h := home(t)
+ cwd := t.TempDir()
+ t.Chdir(cwd)
+ code, out, errOut := runCLI(t, "-c=~/k/krino.conf", "init")
+ if code != 0 {
+ t.Fatalf("init: %d %q %q", code, out, errOut)
+ }
+ want := filepath.Join(h, "k", "krino.conf")
+ if _, err := os.Stat(want); err != nil {
+ t.Fatalf("%s not created: %v", want, err)
+ }
+ if _, err := os.Lstat(filepath.Join(cwd, "~")); !os.IsNotExist(err) {
+ t.Fatalf(`"~" created in the current directory: %v`, err)
+ }
+}
+
+func TestConfigFlag(t *testing.T) {
+ h := home(t)
+ conf := filepath.Join(h, "elsewhere", "krino.conf")
+ if code, _, errOut := runCLI(t, "init", "-c", conf); code != 0 {
+ t.Fatalf("init -c: %q", errOut)
+ }
+ for _, args := range [][]string{{"-c", conf, "check"}, {"check", "-c", conf}} {
+ if code, out, errOut := runCLI(t, args...); code != 0 || !strings.Contains(out, "config: ~/elsewhere/krino.conf") {
+ t.Errorf("%v: %d %q %q", args, code, out, errOut)
+ }
+ }
+}
+
+func TestCommandErrors(t *testing.T) {
+ home(t)
+ tests := []struct {
+ args []string
+ want string
+ }{
+ {[]string{"check"}, "not found; create it with: krino init"},
+ {[]string{"new", "onlyname"}, "usage: krino new NAME PATH"},
+ {[]string{"init", "extra"}, "init takes no arguments"},
+ }
+ for _, tt := range tests {
+ if code, _, errOut := runCLI(t, tt.args...); code != 2 || !strings.Contains(errOut, tt.want) {
+ t.Errorf("%v: %d %q, want %q", tt.args, code, errOut, tt.want)
+ }
+ }
+}