merge lavoro/goldrake-u11 (secondo giro 27/09)
This commit is contained in:
+52
-1
@@ -68,14 +68,65 @@ def test_i_sorveglianti_vengono_prima_delle_voci_grandi(tmp_path):
|
||||
|
||||
|
||||
def test_il_troncamento_e_dichiarato(tmp_path, monkeypatch):
|
||||
"""CLAUDE.md e' la prima voce e ha un tetto SUO (MAX_CHARS_CLAUDE_MD, #37 C12): si monkeypatcha
|
||||
quello, non il MAX_CHARS_VOCE generico, che non lo tocca piu'."""
|
||||
r = _radice(tmp_path)
|
||||
(r / "CLAUDE.md").write_text("x" * 1000)
|
||||
monkeypatch.setattr(R, "MAX_CHARS_VOCE", 100)
|
||||
monkeypatch.setattr(R, "MAX_CHARS_CLAUDE_MD", 100)
|
||||
n, t, tr = R.materiale(r, ADESSO)[0]
|
||||
assert tr and "[… troncato a 100 caratteri su 1,000]" in t
|
||||
assert "[TRONCATO]" in R.costruisci_prompt([(n, t, tr)], ADESSO)
|
||||
|
||||
|
||||
def test_claude_md_ha_un_tetto_suo_distinto_dal_generico(tmp_path, monkeypatch):
|
||||
"""#37 C12: CLAUDE.md sfiora MAX_CHARS_VOCE con un margine minimo — deve avere un tetto suo
|
||||
piu' largo, cosi' un piccolo aggiornamento non lo tronca."""
|
||||
r = _radice(tmp_path)
|
||||
n_chars = R.MAX_CHARS_VOCE + 1_000 # sopra il generico, ma sotto MAX_CHARS_CLAUDE_MD
|
||||
assert n_chars < R.MAX_CHARS_CLAUDE_MD
|
||||
(r / "CLAUDE.md").write_text("x" * n_chars)
|
||||
n, t, tr = R.materiale(r, ADESSO)[0]
|
||||
assert n.startswith("CLAUDE.md")
|
||||
assert not tr, "sotto il tetto SUO (150k): non deve troncare, anche se supera i 90k generici"
|
||||
|
||||
|
||||
def test_voce_vicina_al_tetto_e_avvisata_nel_prompt_e_nel_rapporto(tmp_path, monkeypatch):
|
||||
"""#37 C12: al 95% del tetto (non ancora troncata) l'avviso entra nel testo, e da li' arriva
|
||||
sia al prompt del revisore sia alla tabella del rapporto — come [TRONCATO] oggi."""
|
||||
r = _radice(tmp_path)
|
||||
monkeypatch.setattr(R, "MAX_CHARS_CLAUDE_MD", 10_000)
|
||||
(r / "CLAUDE.md").write_text("x" * 9_600) # 96% di 10.000, margine largo per la nota
|
||||
n, t, tr = R.materiale(r, ADESSO)[0]
|
||||
assert not tr, "non e' troncata: e' vicina"
|
||||
assert R._MARCA_VICINO_TETTO in t
|
||||
assert "[VICINO AL TETTO]" in R.costruisci_prompt([(n, t, tr)], ADESSO)
|
||||
rap = R.rapporto("revisione", None, "ok", [], "claude-fable-5-1", ADESSO, [(n, t, tr)])
|
||||
assert "| quasi |" in rap
|
||||
|
||||
|
||||
def test_voce_lontana_dal_tetto_non_e_avvisata(tmp_path):
|
||||
voci = R.materiale(_radice(tmp_path), ADESSO)
|
||||
claude_md = [t for n, t, tr in voci if n.startswith("CLAUDE.md")][0]
|
||||
assert R._MARCA_VICINO_TETTO not in claude_md
|
||||
|
||||
|
||||
def test_il_totale_resta_sotto_il_tetto_anche_se_la_somma_dei_tetti_lo_supera(tmp_path, monkeypatch):
|
||||
"""#37 C12: CLAUDE.md (150k) + il resto delle voci (90k l'una) puo' superare facilmente i 400k
|
||||
di MAX_CHARS_TOTALE in somma — il tetto totale e' applicato A PARTE, a valle, e resta il vero
|
||||
vincolo: non deve MAI sfondare, qualunque sia il tetto di ogni singola voce."""
|
||||
r = _radice(tmp_path)
|
||||
(r / "CLAUDE.md").write_text("x" * R.MAX_CHARS_CLAUDE_MD) # al SUO tetto: 150k
|
||||
j = r / "docs" / "journal"
|
||||
for i in range(1, 10): # sovrascrive i giornali della finestra
|
||||
g = (ADESSO - timedelta(days=i)).date().isoformat()
|
||||
(j / f"{g}.md").write_text("y" * R.MAX_CHARS_VOCE) # ognuno al SUO tetto: 90k
|
||||
voci = R.materiale(r, ADESSO)
|
||||
tot = sum(len(t) for _, t, _ in voci)
|
||||
somma_tetti = sum(R._cap_voce(n) for n, _, _ in voci)
|
||||
assert somma_tetti > R.MAX_CHARS_TOTALE, "il caso e' quello che sfonderebbe se il totale non fosse a parte"
|
||||
assert tot <= R.MAX_CHARS_TOTALE
|
||||
|
||||
|
||||
def test_il_prompt_porta_le_regole_e_la_data(tmp_path):
|
||||
p = R.costruisci_prompt(R.materiale(_radice(tmp_path), ADESSO), ADESSO)
|
||||
assert "DATA DELLA REVISIONE: 2026-09-14 06:15Z" in p
|
||||
|
||||
Reference in New Issue
Block a user