import tempfile
import shutil
import subprocess
import os
import pytest
from pathlib import Path
import prollytree
class TestDiffFunctionality:
def setup_method(self):
self.temp_dir = tempfile.mkdtemp()
subprocess.run(["git", "init"], cwd=self.temp_dir, check=True, capture_output=True)
subprocess.run(["git", "config", "user.name", "Test User"], cwd=self.temp_dir, check=True)
subprocess.run(["git", "config", "user.email", "test@example.com"], cwd=self.temp_dir, check=True)
self.store_path = Path(self.temp_dir) / "data"
self.store_path.mkdir(parents=True, exist_ok=True)
self.original_cwd = os.getcwd()
os.chdir(str(self.store_path))
def teardown_method(self):
os.chdir(self.original_cwd)
shutil.rmtree(self.temp_dir, ignore_errors=True)
def test_diff_between_commits(self):
store = prollytree.VersionedKvStore(str(self.store_path))
store.insert(b"key1", b"value1")
store.insert(b"key2", b"value2")
commit1 = store.commit("Initial commit")
store.insert(b"key3", b"value3") store.update(b"key1", b"value1_modified") store.delete(b"key2") commit2 = store.commit("Second commit")
diffs = store.diff(commit1, commit2)
diff_map = {diff.key: diff.operation for diff in diffs}
assert len(diffs) == 3
assert b"key1" in diff_map
assert b"key2" in diff_map
assert b"key3" in diff_map
key1_op = diff_map[b"key1"]
assert key1_op.operation_type == "Modified"
assert key1_op.old_value == b"value1"
assert key1_op.new_value == b"value1_modified"
key2_op = diff_map[b"key2"]
assert key2_op.operation_type == "Removed"
assert key2_op.value == b"value2"
key3_op = diff_map[b"key3"]
assert key3_op.operation_type == "Added"
assert key3_op.value == b"value3"
def test_diff_between_branches(self):
store = prollytree.VersionedKvStore(str(self.store_path))
store.insert(b"shared", b"initial")
store.insert(b"main_only", b"main_value")
store.commit("Initial commit on main")
store.create_branch("feature")
store.update(b"shared", b"feature_value")
store.insert(b"feature_only", b"feature_data")
store.delete(b"main_only")
store.commit("Changes on feature branch")
diffs = store.diff("main", "feature")
assert len(diffs) == 3
diff_map = {diff.key: diff.operation for diff in diffs}
shared_op = diff_map[b"shared"]
assert shared_op.operation_type == "Modified"
assert shared_op.old_value == b"initial"
assert shared_op.new_value == b"feature_value"
main_only_op = diff_map[b"main_only"]
assert main_only_op.operation_type == "Removed"
feature_only_op = diff_map[b"feature_only"]
assert feature_only_op.operation_type == "Added"
def test_current_commit(self):
store = prollytree.VersionedKvStore(str(self.store_path))
store.insert(b"key1", b"value1")
commit1 = store.commit("First commit")
current = store.current_commit()
assert current == commit1
store.insert(b"key2", b"value2")
commit2 = store.commit("Second commit")
current = store.current_commit()
assert current == commit2
store.create_branch("test-branch")
store.insert(b"key3", b"value3")
commit3 = store.commit("Third commit on branch")
current = store.current_commit()
assert current == commit3
store.checkout("main")
current = store.current_commit()
assert current == commit2
def test_diff_with_no_changes(self):
store = prollytree.VersionedKvStore(str(self.store_path))
store.insert(b"key1", b"value1")
commit1 = store.commit("First commit")
diffs = store.diff(commit1, commit1)
assert len(diffs) == 0
def test_diff_representation(self):
store = prollytree.VersionedKvStore(str(self.store_path))
store.insert(b"key1", b"value1")
commit1 = store.commit("First")
store.update(b"key1", b"value2")
commit2 = store.commit("Second")
diffs = store.diff(commit1, commit2)
assert len(diffs) == 1
diff = diffs[0]
repr_str = repr(diff)
assert "key1" in repr_str
assert "Modified" in repr_str
op_repr = repr(diff.operation)
assert "Modified" in op_repr
assert "old_size" in op_repr
assert "new_size" in op_repr
def test_get_commits_for_key_functionality(self):
store = prollytree.VersionedKvStore(str(self.store_path))
store.insert(b"tracked_key", b"value1")
store.insert(b"other_key", b"other_value")
commit1 = store.commit("First commit")
store.update(b"tracked_key", b"value2")
commit2 = store.commit("Second commit - tracked_key changed")
store.insert(b"another_key", b"another_value")
commit3 = store.commit("Third commit - no tracked_key change")
commits_for_key = store.get_commits_for_key(b"tracked_key")
assert len(commits_for_key) == 2
commit_ids = [commit['id'] for commit in commits_for_key]
assert commit2 in commit_ids assert commit1 in commit_ids assert commit3 not in [c['id'] for c in commits_for_key]
assert commits_for_key[0]['id'] == commit2
if __name__ == "__main__":
pytest.main([__file__, "-v"])