aboutsummaryrefslogtreecommitdiff
path: root/gui/internal/model/plan_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'gui/internal/model/plan_test.go')
-rw-r--r--gui/internal/model/plan_test.go38
1 files changed, 38 insertions, 0 deletions
diff --git a/gui/internal/model/plan_test.go b/gui/internal/model/plan_test.go
index 1bae2c5..241a049 100644
--- a/gui/internal/model/plan_test.go
+++ b/gui/internal/model/plan_test.go
@@ -505,3 +505,41 @@ func TestCloseDuringApplyIsRefused(t *testing.T) {
t.Errorf("the apply itself failed: %v", applyErr)
}
}
+
+// TestKeepThisCopyTwiceIsRefused: "keep this copy" writes a Displaces
+// straight into the chain. The engine refuses to plan two steps that
+// displace one path - the second would destroy what the first just put
+// there - but the window went round that code. Both rows then reported
+// "done" while the first file was in the Trash.
+func TestKeepThisCopyTwiceIsRefused(t *testing.T) {
+ conf := "(path \"~/dl\")\n(rule \"dupes\" (when (duplicate)) (move \"Dupes\"))\n"
+ e, h := sandboxDir(t, conf, map[string]string{
+ "x.pdf": "the same bytes", "y.pdf": "the same bytes", "a.pdf": "the same bytes",
+ })
+ _ = h
+ tab, err := Plan(context.Background(), e, e.Dirs[0])
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { tab.Close() })
+
+ var dupes []int
+ for i, r := range tab.Rows {
+ if r.DuplicateOf != "" {
+ dupes = append(dupes, i)
+ }
+ }
+ if len(dupes) < 2 {
+ t.Skipf("fixture produced %d duplicate rows, need two", len(dupes))
+ }
+ if err := tab.KeepThisCopy(dupes[0]); err != nil {
+ t.Fatalf("the first choice was refused: %v", err)
+ }
+ err = tab.KeepThisCopy(dupes[1])
+ if err == nil {
+ t.Fatal("two files were allowed to replace the same one; the second would trash what the first filed")
+ }
+ if !strings.Contains(err.Error(), "already") {
+ t.Errorf("refusal reads %q; it should say the place is already spoken for", err)
+ }
+}