diff options
Diffstat (limited to 'internal/engine/undo_identity_test.go')
| -rw-r--r-- | internal/engine/undo_identity_test.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/internal/engine/undo_identity_test.go b/internal/engine/undo_identity_test.go index 9c93b3b..d4169be 100644 --- a/internal/engine/undo_identity_test.go +++ b/internal/engine/undo_identity_test.go @@ -223,3 +223,54 @@ func TestUndoLeavesNoDirectoriesBehind(t *testing.T) { t.Errorf("dl/Out is left behind: %v", err) } } + +// TestUndoCanBeFinishedAfterAFailure: an undo whose last reversal failed +// (something took the original name) leaves the file part way back; once +// the obstacle is gone, undoing the same run again offers only the step +// that is left, and finishes it (review M10). +func TestUndoCanBeFinishedAfterAFailure(t *testing.T) { + e, run, h, logPath := appliedRun(t, map[string]map[string]string{"dl": {"a.pdf": "one"}}, + map[string]string{"dl": "(path \"~/dl\")\n(rule \"r\" (rename \"r-{name}\") (move \"Out\"))\n"}) + up, err := e.PlanUndo(run) + if err != nil { + t.Fatal(err) + } + blocker := filepath.Join(h, "dl", "a.pdf") + if err := os.WriteFile(blocker, []byte("in the way"), 0o644); err != nil { + t.Fatal(err) + } + undo := func(up *UndoPlan) *ApplyResult { + t.Helper() + j, err := journal.Open(logPath) + if err != nil { + t.Fatal(err) + } + defer j.Close() + res, err := e.ApplyUndo(context.Background(), up, j, journal.NewRunID(time.Now())) + if err != nil { + t.Fatal(err) + } + return res + } + if res := undo(up); res.Failed != 1 { + t.Fatalf("first undo: Failed = %d, want 1 (the rename back is blocked)", res.Failed) + } + if err := os.Remove(blocker); err != nil { + t.Fatal(err) + } + time.Sleep(10 * time.Millisecond) // a new run id + again, err := e.PlanUndo(run) + if err != nil { + t.Fatal(err) + } + f := undoFileNamed(t, again, "dl", "a.pdf") + if f.Refused != "" || len(f.Steps) != 1 || f.Steps[0].Action != "undo-rename" { + t.Fatalf("second plan: %+v; want one undo-rename step", f) + } + if res := undo(again); res.Failed != 0 || res.Applied != 1 { + t.Fatalf("second undo: %+v", res) + } + if b, err := os.ReadFile(filepath.Join(h, "dl", "a.pdf")); err != nil || string(b) != "one" { + t.Errorf("dl/a.pdf = %q, %v; want the original back", b, err) + } +} |
