"""Test di scripts/archivio_sorgente.py (TieMeasureFlow#109): repo temporaneo con un submodule finto. Uso: uv run --python 3.13 --extra dev pytest -q scripts/tests/test_archivio_sorgente.py """ import importlib.util import subprocess import zipfile from pathlib import Path import pytest _spec = importlib.util.spec_from_file_location( "archivio_sorgente", Path(__file__).resolve().parents[1] / "archivio_sorgente.py") archivio = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(archivio) GIT = ["git", "-c", "core.autocrlf=false", "-c", "protocol.file.allow=always", "-c", "user.name=t", "-c", "user.email=t@t", "-c", "commit.gpgsign=false"] def _g(cartella, *args): r = subprocess.run([*GIT, "-C", str(cartella), *args], capture_output=True, text=True) assert r.returncode == 0, r.stderr return r.stdout.strip() def _repo(tmp_path, nome): d = tmp_path / nome d.mkdir() _g(d, "init", "-q", "-b", "main") return d @pytest.fixture def padre(tmp_path): """Repo padre con vendor/visionsuite registrato (submodule finto da un repo locale).""" origine = _repo(tmp_path, "origine") (origine / "motore.py").write_text("x = 1\n") _g(origine, "add", ".") _g(origine, "commit", "-q", "-m", "motore") p = _repo(tmp_path, "padre") (p / "app.py").write_text("print('tmf')\n") _g(p, "add", ".") _g(p, "commit", "-q", "-m", "app") _g(p, "submodule", "add", "-q", str(origine), "vendor/visionsuite") _g(p, "commit", "-q", "-m", "submodule") return p def test_zip_con_repo_submodule_e_versione(padre, tmp_path): atteso = _g(padre, "ls-tree", "HEAD", "vendor/visionsuite").split()[2] out = tmp_path / "o" / "tmf.zip" assert archivio.crea_archivio(padre, out) == atteso with zipfile.ZipFile(out) as z: nomi = z.namelist() assert "app.py" in nomi and "vendor/visionsuite/motore.py" in nomi dati = z.read("vision-engine-version.txt") assert dati == atteso.encode("ascii") and len(dati) == 40 assert not dati.startswith(b"\xef\xbb\xbf") and b"\n" not in dati # niente BOM, niente a capo def test_sha_resta_quello_registrato_se_il_submodule_avanza(padre, tmp_path): registrato = _g(padre, "ls-tree", "HEAD", "vendor/visionsuite").split()[2] sub = padre / "vendor" / "visionsuite" (sub / "nuovo.py").write_text("y = 2\n") _g(sub, "add", ".") _g(sub, "commit", "-q", "-m", "avanti non registrato") assert _g(sub, "rev-parse", "HEAD") != registrato out = tmp_path / "tmf.zip" assert archivio.crea_archivio(padre, out) == registrato with zipfile.ZipFile(out) as z: assert z.read("vision-engine-version.txt").decode() == registrato assert "vendor/visionsuite/nuovo.py" not in z.namelist() # contenuto del commit registrato def test_submodule_non_inizializzato_errore_e_nessuno_zip(padre, tmp_path): clone = tmp_path / "clone" _g(tmp_path, "clone", "-q", str(padre), str(clone)) # senza --recurse-submodules out = tmp_path / "tmf.zip" with pytest.raises(archivio.ErroreArchivio, match="inizializzato"): archivio.crea_archivio(clone, out) assert not out.exists() and not list(tmp_path.glob("*.tmp")) # nessuno zip ne' temporaneo def test_cli_esce_1_con_messaggio(padre, tmp_path, capsys, monkeypatch): clone = tmp_path / "clone" _g(tmp_path, "clone", "-q", str(padre), str(clone)) originale = archivio.crea_archivio # la CLI lavora sul repo che contiene lo script: la si dirotta sul clone senza submodule monkeypatch.setattr(archivio, "crea_archivio", lambda r, o, ref="HEAD": originale(clone, o, ref)) assert archivio.main(["--out", str(tmp_path / "x.zip")]) == 1 assert "ERRORE" in capsys.readouterr().err