aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/explain_test.go
blob: 4d304f9f7d3620adbd08a4e596c2d7354b2b5743 (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
// SPDX-License-Identifier: GPL-3.0-or-later

package engine

import (
	"context"
	"path/filepath"
	"reflect"
	"strings"
	"testing"

	"krino/internal/plan"
)

// TestExplainReportsCapturesAndChain: explain returns what each matching
// rule captured and the steps the file would get, so a GUI can show
// "{1}=2026" and the destination without planning the whole directory
// (GUI design §1.3).
func TestExplainReportsCapturesAndChain(t *testing.T) {
	h, dl := excludeTree(t, map[string]string{"Screenshot_2026-09-01.png": "x"})
	main := writeConfig(t, h, `(include "dl")`, map[string]string{"dl": `
(path "~/dl")
(rule "shots" (when (name "^Screenshot_(\d{4})-(\d{2})")) (move "Pictures/{1}-{2}") (stop))
`})
	e, errs := Load(main)
	if len(errs) > 0 {
		t.Fatal(errs)
	}
	x, err := e.Explain(context.Background(), filepath.Join(dl, "Screenshot_2026-09-01.png"))
	if err != nil {
		t.Fatal(err)
	}
	if len(x.Rules) != 1 || !reflect.DeepEqual(x.Rules[0].Captures, []string{"Screenshot_2026-09", "2026", "09"}) {
		t.Fatalf("captures = %+v", x.Rules)
	}
	if len(x.Chain) != 1 || x.Chain[0].Kind != plan.Move || !strings.HasSuffix(x.Chain[0].Dst, "/dl/Pictures/2026-09/Screenshot_2026-09-01.png") {
		t.Fatalf("chain = %+v", x.Chain)
	}
}

// TestExplainChainMatchesThePlan: the chain explain reports is the one the
// directory's plan gives the same file, conflicts and skips included.
func TestExplainChainMatchesThePlan(t *testing.T) {
	h, dl := excludeTree(t, map[string]string{"a.pdf": "one", "Out/a.pdf": "taken"})
	main := writeConfig(t, h, `(include "dl")`, map[string]string{"dl": `
(path "~/dl")
(ignore "Out/")
(rule "r" (when (name "^a")) (rename "b.pdf") (move "Out"))
`})
	e, errs := Load(main)
	if len(errs) > 0 {
		t.Fatal(errs)
	}
	dp, err := e.Plan(context.Background(), e.Dirs[0], plan.NewClaims())
	if err != nil {
		t.Fatal(err)
	}
	x, err := e.Explain(context.Background(), filepath.Join(dl, "a.pdf"))
	if err != nil {
		t.Fatal(err)
	}
	if len(dp.Chains) != 1 || !reflect.DeepEqual(x.Chain, dp.Chains[0].Steps) {
		t.Errorf("explain chain %+v\nplan chain %+v", x.Chain, dp.Chains[0].Steps)
	}
}