aboutsummaryrefslogtreecommitdiff
path: root/cmd/krino/commands_test.go
blob: 2156da216e82325be5318978d4bbe316a1f8935d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-License-Identifier: GPL-3.0-or-later

package main

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// home gives each test its own HOME with no XDG overrides.
func home(t *testing.T) string {
	t.Helper()
	h := t.TempDir()
	t.Setenv("HOME", h)
	for _, v := range []string{"XDG_CONFIG_HOME", "XDG_STATE_HOME", "XDG_DATA_HOME", "XDG_CACHE_HOME"} {
		t.Setenv(v, "")
	}
	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)
		}
	}
}