diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-17 10:05:55 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-17 10:05:55 +0200 |
| commit | 47b6776c2cb9b017ad95acb5aae8e34b8776fc7c (patch) | |
| tree | 3efb4a2f2c36f4537a3fe1377cfb010fd63072ec /gui/internal/model/sort_test.go | |
| parent | 0e067e693609589d46f5aa6e161b95cc905987cc (diff) | |
| download | krino-47b6776c2cb9b017ad95acb5aae8e34b8776fc7c.tar.gz krino-47b6776c2cb9b017ad95acb5aae8e34b8776fc7c.zip | |
gui: sort the plan by name, size, age, action or rule
Diffstat (limited to 'gui/internal/model/sort_test.go')
| -rw-r--r-- | gui/internal/model/sort_test.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/gui/internal/model/sort_test.go b/gui/internal/model/sort_test.go new file mode 100644 index 0000000..0b3a01d --- /dev/null +++ b/gui/internal/model/sort_test.go @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package model + +import ( + "os" + "path/filepath" + "testing" + "time" +) + +// names is the rows an order leaves, for the assertions below. +func names(t *PlanTab, shown []int) []string { + var out []string + for _, i := range shown { + out = append(out, t.Rows[i].Rel) + } + return out +} + +func same(a []string, b ...string) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +// TestSorted: each order reads the way its label says, and the default +// leaves the plan as krino made it. +func TestSorted(t *testing.T) { + conf := "(path \"~/dl\")\n" + + "(rule \"pdfs\" (when (type pdf)) (move \"Docs\") (stop))\n" + + "(rule \"rest\" (move \"Other\"))\n" + e, h := sandboxDir(t, conf, map[string]string{ + "big.pdf": "0123456789abcdef", "small.txt": "x", "middle.pdf": "0123456789", + }) + // Distinct times, so age has something to order by. + now := time.Now() + for name, ago := range map[string]time.Duration{ + "big.pdf": 3 * time.Hour, "small.txt": 90 * 24 * time.Hour, "middle.pdf": 24 * time.Hour, + } { + p := filepath.Join(h, "dl", name) + when := now.Add(-ago) + if err := os.Chtimes(p, when, when); err != nil { + t.Fatal(err) + } + } + tab := planTab(t, e) + all := tab.Matching("") + + if got := names(tab, tab.Sorted(all, SortDefault)); len(got) != 3 { + t.Fatalf("default = %v", got) + } + if got := names(tab, tab.Sorted(all, SortName)); !same(got, "big.pdf", "middle.pdf", "small.txt") { + t.Errorf("by name = %v", got) + } + if got := names(tab, tab.Sorted(all, SortSize)); !same(got, "big.pdf", "middle.pdf", "small.txt") { + t.Errorf("by size = %v", got) + } + if got := names(tab, tab.Sorted(all, SortAge)); !same(got, "small.txt", "middle.pdf", "big.pdf") { + t.Errorf("by age = %v, want the oldest first", got) + } + if got := names(tab, tab.Sorted(all, SortRule)); !same(got, "big.pdf", "middle.pdf", "small.txt") { + t.Errorf("by rule = %v, want pdfs before rest", got) + } + // An order krino does not know leaves the plan alone rather than + // guessing at one. + if got := names(tab, tab.Sorted(all, "nonsense")); !same(got, names(tab, all)...) { + t.Errorf("an unknown order changed the list: %v", got) + } + // Sorting never changes the plan itself. + if len(tab.Rows) != 3 || tab.Rows[0].Rel != names(tab, all)[0] { + t.Error("the plan's own order changed") + } +} + +// TestSortedIsStable: files that compare the same keep the plan's order, so +// the list does not shuffle under the eye. +func TestSortedIsStable(t *testing.T) { + conf := "(path \"~/dl\")\n(rule \"all\" (move \"Out\"))\n" + e, _ := sandboxDir(t, conf, map[string]string{"a.txt": "x", "b.txt": "x", "c.txt": "x"}) + tab := planTab(t, e) + all := tab.Matching("") + first := names(tab, tab.Sorted(all, SortSize)) + for i := 0; i < 5; i++ { + if got := names(tab, tab.Sorted(all, SortSize)); !same(got, first...) { + t.Fatalf("run %d = %v, want %v", i, got, first) + } + } +} |
