Update tests with --restore flag

This commit is contained in:
2025-12-15 17:19:17 +00:00
parent 0dc9b827f9
commit 537397ac36

View File

@@ -72,7 +72,7 @@ def test_strip_header_removes_header():
def test_strip_header_preserves_shebang(): def test_strip_header_preserves_shebang():
text = "#!/usr/bin/env python3\nprint('hi')\n" text = "#!/usr/bin/env python3\nprint('hi')\n"
out = mirro.strip_mirro_header(text) out = mirro.strip_mirro_header(text)
assert out == text # unchanged assert out == text
def test_strip_header_non_header_file(): def test_strip_header_non_header_file():
@@ -297,29 +297,6 @@ def test_main_permission_denied_create(tmp_path, monkeypatch, capsys):
assert "Need elevated privileges to create" in capsys.readouterr().out assert "Need elevated privileges to create" in capsys.readouterr().out
# ============================================================
# Editor ordering: non-nano branch
# ============================================================
def test_main_editor_non_nano(tmp_path, monkeypatch, capsys):
target = tmp_path / "vim.txt"
target.write_text("old\n")
def fake_call(cmd):
temp = Path(cmd[1])
temp.write_text("edited\n")
monkeypatch.setenv("EDITOR", "vim")
monkeypatch.setattr(subprocess, "call", fake_call)
monkeypatch.setattr(os, "access", lambda p, m: True)
with patch("sys.argv", ["mirro", str(target)]):
mirro.main()
assert target.read_text() == "edited\n"
# ============================================================ # ============================================================
# --list # --list
# ============================================================ # ============================================================
@@ -376,8 +353,10 @@ def test_restore_last_no_backups(tmp_path, capsys):
): ):
result = mirro.main() result = mirro.main()
out = capsys.readouterr().out
assert result == 1 assert result == 1
assert "No backups found" in capsys.readouterr().out assert "No history found for" in out
assert str(target) in out
def test_restore_last_success(tmp_path, capsys): def test_restore_last_success(tmp_path, capsys):
@@ -401,7 +380,6 @@ def test_restore_last_success(tmp_path, capsys):
b1.write_text(mirro_header + "old1") b1.write_text(mirro_header + "old1")
b2.write_text(mirro_header + "old2") b2.write_text(mirro_header + "old2")
# ensure newest
os.utime(b2, (time.time(), time.time())) os.utime(b2, (time.time(), time.time()))
with patch( with patch(
@@ -415,156 +393,93 @@ def test_restore_last_success(tmp_path, capsys):
# ============================================================ # ============================================================
# --prune-backups # --restore (new)
# ============================================================ # ============================================================
def test_prune_all(tmp_path, capsys): def test_restore_backup_to_original_location(tmp_path, capsys):
d = tmp_path / "bk" backup_dir = tmp_path / "bk"
d.mkdir() backup_dir.mkdir()
(d / "a").write_text("x")
(d / "b").write_text("y")
with patch( original_dir = tmp_path / "orig"
"sys.argv", ["mirro", "--prune-backups=all", "--backup-dir", str(d)] original_dir.mkdir()
):
mirro.main()
out = capsys.readouterr().out target = original_dir / "file.txt"
assert "Removed ALL backups" in out
assert not any(d.iterdir())
mirro_header = (
def test_prune_numeric(tmp_path, capsys):
d = tmp_path / "bk"
d.mkdir()
old = d / "old"
new = d / "new"
old.write_text("x")
new.write_text("y")
one_day_seconds = 86400
os.utime(
old,
(
time.time() - one_day_seconds * 10,
time.time() - one_day_seconds * 10,
),
)
os.utime(new, None)
with patch(
"sys.argv", ["mirro", "--prune-backups=5", "--backup-dir", str(d)]
):
mirro.main()
out = capsys.readouterr().out
assert "Removed 1" in out
assert new.exists()
assert not old.exists()
def test_prune_default_env(tmp_path, monkeypatch, capsys):
monkeypatch.setenv("MIRRO_BACKUPS_LIFE", "1")
d = tmp_path / "bk"
d.mkdir()
f = d / "x"
f.write_text("hi")
os.utime(f, (time.time() - 86400 * 2, time.time() - 86400 * 2))
with patch(
"sys.argv", ["mirro", "--prune-backups", "--backup-dir", str(d)]
):
mirro.main()
assert "Removed 1" in capsys.readouterr().out
def test_prune_invalid_env(tmp_path, monkeypatch, capsys):
monkeypatch.setenv("MIRRO_BACKUPS_LIFE", "nope")
d = tmp_path / "bk"
d.mkdir()
with patch(
"sys.argv", ["mirro", "--prune-backups", "--backup-dir", str(d)]
):
mirro.main()
out = capsys.readouterr().out
assert "Invalid MIRRO_BACKUPS_LIFE value" in out
def test_prune_invalid_arg(tmp_path, capsys):
with patch("sys.argv", ["mirro", "--prune-backups=zzz"]):
result = mirro.main()
assert result == 1
assert "Invalid value for --prune-backups" in capsys.readouterr().out
# ============================================================
# --diff tests
# ============================================================
def test_diff_basic(tmp_path, capsys):
d = tmp_path / "bk"
d.mkdir()
file = tmp_path / "t.txt"
file.write_text("line1\nline2\n")
backup = d / "t.txt.orig.20250101T010203"
backup.write_text(
"# ---------------------------------------------------\n" "# ---------------------------------------------------\n"
"# mirro backup\n" "# mirro backup\n"
"# whatever\n" f"# Original file: {target}\n"
"# Timestamp: test\n"
"# Delete this header if you want to restore the file\n"
"# ---------------------------------------------------\n"
"\n" "\n"
"line1\nold\n" )
backup = backup_dir / "file.txt.orig.20250101T010203"
backup.write_text(mirro_header + "restored content\n")
with patch(
"sys.argv",
["mirro", "--restore", backup.name, "--backup-dir", str(backup_dir)],
):
result = mirro.main()
assert result == 0
assert target.exists()
assert target.read_text() == "restored content\n"
assert "Restored" in capsys.readouterr().out
def test_restore_missing_backup(tmp_path, capsys):
backup_dir = tmp_path / "bk"
backup_dir.mkdir()
with patch(
"sys.argv",
[
"mirro",
"--restore",
"nope.orig.123",
"--backup-dir",
str(backup_dir),
],
):
result = mirro.main()
assert result == 1
assert "Backup not found" in capsys.readouterr().out
def test_restore_missing_original_path_in_header(tmp_path, capsys):
backup_dir = tmp_path / "bk"
backup_dir.mkdir()
bad_backup = backup_dir / "x.txt.orig.123"
bad_backup.write_text(
"# ---------------------------------------------------\n"
"# mirro backup\n"
"# Timestamp: test\n"
"\n"
"data\n"
) )
with patch( with patch(
"sys.argv", "sys.argv",
["mirro", "--diff", str(file), backup.name, "--backup-dir", str(d)], [
): "mirro",
mirro.main() "--restore",
bad_backup.name,
out = capsys.readouterr().out "--backup-dir",
str(backup_dir),
assert "--- a/t.txt" in out ],
assert "+++ b/t.txt" in out
assert "@@" in out
assert "-old" in out
assert "+line2" in out
def test_diff_wrong_backup_name_rejected(tmp_path, capsys):
d = tmp_path / "bk"
d.mkdir()
file = tmp_path / "foo.txt"
file.write_text("hello\n")
bad = d / "bar.txt.orig.20250101T010203"
bad.write_text("stuff\n")
with patch(
"sys.argv",
["mirro", "--diff", str(file), bad.name, "--backup-dir", str(d)],
): ):
result = mirro.main() result = mirro.main()
out = capsys.readouterr().out
assert result == 1 assert result == 1
assert "does not match the file being diffed" in out assert (
assert "foo.txt.orig." in out "Could not determine original file location" in capsys.readouterr().out
)
# ============================================================ # ============================================================
@@ -575,7 +490,7 @@ def test_diff_wrong_backup_name_rejected(tmp_path, capsys):
def test_status_no_backups(tmp_path, monkeypatch, capsys): def test_status_no_backups(tmp_path, monkeypatch, capsys):
monkeypatch.chdir(tmp_path) monkeypatch.chdir(tmp_path)
backup_dir = tmp_path / "bk" # no backups inside backup_dir = tmp_path / "bk"
with patch( with patch(
"sys.argv", ["mirro", "--status", "--backup-dir", str(backup_dir)] "sys.argv", ["mirro", "--status", "--backup-dir", str(backup_dir)]
): ):
@@ -593,25 +508,12 @@ def test_status_backups_found(tmp_path, monkeypatch, capsys):
backup_dir = tmp_path / "bk" backup_dir = tmp_path / "bk"
backup_dir.mkdir() backup_dir.mkdir()
# Files in current directory (tmp_path / "a.txt").write_text("data1")
f1 = tmp_path / "a.txt" (tmp_path / "b.txt").write_text("data2")
f2 = tmp_path / "b.txt"
f1.write_text("data1")
f2.write_text("data2")
# Backups (backup_dir / "a.txt.orig.1").write_text("x")
(backup_dir / "a.txt.orig.20200101T000000").write_text("backup1") (backup_dir / "a.txt.orig.2").write_text("y")
(backup_dir / "a.txt.orig.20200101T010000").write_text("backup2") (backup_dir / "b.txt.orig.3").write_text("z")
(backup_dir / "b.txt.orig.20200202T020000").write_text("backup3")
# mtimes
t1 = time.time() - 200
t2 = time.time() - 100
t3 = time.time() - 50
os.utime(backup_dir / "a.txt.orig.20200101T000000", (t1, t1))
os.utime(backup_dir / "a.txt.orig.20200101T010000", (t2, t2))
os.utime(backup_dir / "b.txt.orig.20200202T020000", (t3, t3))
with patch( with patch(
"sys.argv", ["mirro", "--status", "--backup-dir", str(backup_dir)] "sys.argv", ["mirro", "--status", "--backup-dir", str(backup_dir)]
@@ -619,11 +521,7 @@ def test_status_backups_found(tmp_path, monkeypatch, capsys):
result = mirro.main() result = mirro.main()
out = capsys.readouterr().out out = capsys.readouterr().out
assert result == 0 assert result == 0
assert f"Backed-up files in {cwd}" in out assert f"Files with history in {cwd}:" in out
assert "a.txt" in out assert "a.txt" in out
assert "b.txt" in out assert "b.txt" in out
assert "(2 backup(s)," in out
assert "(1 backup(s)," in out
assert "UTC" in out