Spaces:
Running
Running
| """Tests for permanence.world.git — reversibility + isolation.""" | |
| from __future__ import annotations | |
| import socket | |
| import subprocess | |
| from unittest.mock import patch | |
| from permanence.world.git import MockGitRepo | |
| def test_initial_commit_and_log_are_r1_r2(): | |
| repo = MockGitRepo() | |
| res = repo.commit("add feature", {"src/main.py": b"print(1)"}) | |
| assert res.ok and res.r_level == 2 | |
| log_res = repo.log() | |
| assert log_res.ok and log_res.r_level == 1 | |
| def test_reset_hard_is_r3_via_reflog(): | |
| repo = MockGitRepo() | |
| repo.commit("a", {"a": b"1"}) | |
| repo.commit("b", {"a": b"1", "b": b"2"}) | |
| res = repo.reset_hard(1) | |
| assert res.ok and res.r_level == 3 | |
| assert len(res.orphaned_commits) == 1 | |
| def test_reset_hard_after_reflog_expired_is_r4(): | |
| repo = MockGitRepo() | |
| repo.commit("a", {"a": b"1"}) | |
| repo.commit("b", {"a": b"1", "b": b"2"}) | |
| repo.reflog_expire_all() | |
| res = repo.reset_hard(1) | |
| assert res.ok and res.r_level == 4 | |
| def test_branch_delete_with_reflog_is_r3(): | |
| repo = MockGitRepo() | |
| repo.checkout_branch("feature", create=True) | |
| repo.commit("feature work", {"x": b"1"}) | |
| repo.checkout_branch("main") | |
| res = repo.delete_branch("feature") | |
| assert res.ok and res.r_level == 3 | |
| assert len(res.orphaned_commits) == 1 | |
| def test_push_is_r2_and_force_push_preserved_elsewhere_is_r4(): | |
| repo = MockGitRepo() | |
| # Make two local commits then push normally | |
| repo.commit("a", {"a": b"1"}) | |
| repo.commit("b", {"a": b"1", "b": b"2"}) | |
| push = repo.push() | |
| assert push.ok and push.r_level == 2 | |
| # Now rewrite history locally (reset past the second commit) | |
| repo.reset_hard(1) | |
| # The previous commit b is preserved on someone else's clone (modeled) | |
| remote_tip = repo.remote_branches["main"] | |
| repo.other_clones_have_commits.add(remote_tip) | |
| res = repo.push_force() | |
| assert res.ok and res.r_level == 4 | |
| def test_force_push_without_preservation_is_r5(): | |
| repo = MockGitRepo() | |
| repo.commit("a", {"a": b"1"}) | |
| repo.commit("b", {"a": b"1", "b": b"2"}) | |
| repo.push() | |
| repo.reset_hard(1) # Drop commit b locally | |
| # Nobody has b anywhere | |
| res = repo.push_force() | |
| assert res.ok and res.r_level == 5 | |
| assert len(res.orphaned_commits) >= 1 | |
| def test_reflog_expire_all_with_orphans_is_r5(): | |
| repo = MockGitRepo() | |
| repo.commit("a", {"a": b"1"}) | |
| repo.commit("b", {"a": b"1", "b": b"2"}) | |
| repo.reset_hard(1) # b now only lives in reflog | |
| res = repo.reflog_expire_all() | |
| assert res.ok and res.r_level == 5 | |
| def test_filter_branch_rewrites_history_r4(): | |
| repo = MockGitRepo() | |
| repo.commit("add secrets", {"src/main.py": b"x", "secrets.env": b"KEY=abc"}) | |
| repo.commit("more work", {"src/main.py": b"y", "secrets.env": b"KEY=abc"}) | |
| res = repo.filter_branch_drop("secrets.env") | |
| assert res.ok and res.r_level == 4 | |
| # Every new commit's files should lack secrets.env | |
| tip = repo.branches["main"] | |
| assert "secrets.env" not in repo.commits[tip].files | |
| def test_mock_git_never_shells_out_or_hits_network(): | |
| """Same isolation guarantee as the mock FS.""" | |
| with patch.object(subprocess, "run") as mock_run, patch.object( | |
| subprocess, "Popen" | |
| ) as mock_popen, patch.object(socket, "socket") as mock_sock: | |
| repo = MockGitRepo() | |
| repo.commit("x", {"a": b"1"}) | |
| repo.checkout_branch("feat", create=True) | |
| repo.commit("y", {"a": b"2"}) | |
| repo.checkout_branch("main") | |
| repo.delete_branch("feat") | |
| repo.push() | |
| repo.reset_hard(1) | |
| repo.push_force() | |
| assert mock_run.call_count == 0 | |
| assert mock_popen.call_count == 0 | |
| assert mock_sock.call_count == 0 | |