Files
versioning/tests/test_units.py
T
retoorandClaude Opus 5.5 7e05e3d26c Add WebDAV backup, statistics, progress and dashboard
- WebDAV uploader: concurrency, request and bandwidth limits, retry with
  backoff, offline catch-up, encrypted manifests, durability tracking
- Automatic unique remote directory claimed with a conditional PUT
- AES-256-GCM client-side encryption with keyed blob names
- /stats, /progress, /progress/stream and a /dashboard page
- Own ctypes inotify binding with a compact watch tree (263 MB -> 76 MB RSS)
- Directory-path ignore patterns and a forget command
- Indexed range queries instead of LIKE for path prefixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 20:24:04 +02:00

109 lines
3.9 KiB
Python

import asyncio
from pathlib import PurePath
from versiond.db import Database
from versiond.diff import hunks, unified
from versiond.filters import Filters
from versiond.ingest import Coalescer, Repository
from versiond.store import BlobStore
def test_filters_paths():
f = Filters()
ok = ["app.py", "src/main.go", ".env", ".env.production", "Makefile", "pkg/package.json", ".gitignore"]
for p in ok:
assert f.path_reason(PurePath(p)) is None, p
rejected = {
"node_modules/x/index.js": "ignored-directory",
".git/config": "ignored-directory",
"src/__pycache__/a.cpython-312.pyc": "ignored-directory",
"a.pyc": "ignored-extension",
".bashrc_local": "hidden-file",
"notes.txt~": "temporary-file",
"main.py.swp": "ignored-extension",
"venv/lib/x.py": "ignored-directory",
"target/debug/build.rs": "ignored-directory",
"4913": "temporary-file",
"src/pkg.egg-info/PKG-INFO": "ignored-directory",
}
for p, reason in rejected.items():
assert f.path_reason(PurePath(p)) == reason, p
assert f.size_reason(204_800) is None
assert f.size_reason(204_801) == "file-too-large"
assert f.content_reason(b"abc\x00def") == "binary-content"
def test_filter_patterns():
f = Filters(patterns=("*.log", "secret/*"))
assert f.path_reason(PurePath("x/debug.log")) == "ignored-pattern"
assert f.path_reason(PurePath("secret/key.txt")) == "ignored-pattern"
assert f.path_reason(PurePath("src/key.txt")) is None
def test_directory_patterns():
f = Filters(patterns=("app/data/uploads",))
assert f.skip_dir("uploads", "app/data/uploads")
assert not f.skip_dir("uploads", "other/uploads")
assert f.path_reason(PurePath("app/data/uploads/a/b.txt")) == "ignored-pattern"
assert f.path_reason(PurePath("app/data/config.json")) is None
def test_diff_unified():
a = b"one\ntwo\nthree\n"
b = b"one\n2\nthree\nfour\n"
out = unified(hunks(a, b), "a", "b")
assert "-two\n+2\n" in out and "+four\n" in out
assert hunks(b"x y\n", b"x y\n", ignore_whitespace=True) == []
def _repo(tmp_path):
db = Database(tmp_path / "index.sqlite")
return Repository(db, BlobStore(tmp_path / "spool"), Filters())
def test_coalescer_keeps_first_and_last(tmp_path):
repo = _repo(tmp_path)
path = str(tmp_path / "f.py")
async def run():
c = Coalescer(repo, window=0.2, max_hold=1.0, per_hour=100)
statuses = [c.submit(path, f"v{i}\n".encode(), "test", "edit")["status"] for i in range(6)]
await asyncio.sleep(0.5)
return statuses
statuses = asyncio.run(run())
assert statuses[0] == "committed"
assert set(statuses[1:]) == {"coalesced"}
file = repo.db.file_by_path(path)
contents = [repo.blobs.get(v["blob_sha256"]) for v in reversed(repo.db.history(file["id"]))]
assert contents == [b"v0\n", b"v5\n"]
def test_coalescer_rate_limit_keeps_newest(tmp_path):
repo = _repo(tmp_path)
path = str(tmp_path / "f.py")
async def run():
c = Coalescer(repo, window=0.05, max_hold=0.1, per_hour=2)
c.submit(path, b"a", "t", "e")
await asyncio.sleep(0.1)
c.submit(path, b"b", "t", "e")
await asyncio.sleep(0.2)
status = c.submit(path, b"c", "t", "e")["status"]
await asyncio.sleep(0.2)
flushed = c.flush()
return status, flushed
status, flushed = asyncio.run(run())
assert status == "coalesced"
assert flushed == 1 # over the limit it waits, and shutdown still stores it
file = repo.db.file_by_path(path)
assert repo.blobs.get(repo.db.latest_version(file["id"])["blob_sha256"]) == b"c"
def test_dedupe_unchanged(tmp_path):
repo = _repo(tmp_path)
path = str(tmp_path / "f.py")
assert repo.commit(path, b"x", "t", "e")["status"] == "committed"
assert repo.commit(path, b"x", "t", "e")["status"] == "unchanged"