Test: errori di configurazione e CSV, domini.toml non validi, exit code CLI, varianti di report e grafici

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5.5 committed 2026-10-29 13:32:23 +01:00
1 parent bb2e3bd2d4
commit cfb1eb66a5
5 files changed
+104

No files matched your search

+21
View File
@@ -43,3 +43,24 @@ def test_cli_errori(tmp_path):
with pytest.raises(SystemExit) as e:
cli.main(["--config", "/non/esiste.toml", "domini", "x.csv"])
assert e.value.code == 3
def test_cli_domini_non_validi_exit_6(tmp_path):
csv = csv_sintetico(tmp_path)
toml = tmp_path / "d.toml"
toml.write_text('[[dominio]]\ntipo="riposo"\nt0_s=0\nt1_s=10\n[[dominio]]\ntipo="raffreddamento"\nt0_s=20\nt1_s=30\n')
with pytest.raises(SystemExit) as e:
cli.main(["--config", str(RADICE / "config.toml"), "--output", str(tmp_path / "out"), "analizza", str(csv), "--domini", str(toml)])
assert e.value.code == 6
with pytest.raises(SystemExit) as e:
cli.main(["--config", str(RADICE / "config.toml"), "--output", str(tmp_path / "out"), "analizza", str(csv),
"--domini", str(tmp_path / "manca.toml")])
assert e.value.code == 6
def test_cli_csv_non_valido_exit_4(tmp_path):
csv = tmp_path / "vuoto.csv"
csv.write_text("t_ms,T_C,dT_C\n")
with pytest.raises(SystemExit) as e:
cli.main(["--config", str(RADICE / "config.toml"), "--output", str(tmp_path / "out"), "domini", str(csv)])
assert e.value.code == 4
+30
View File
@@ -44,3 +44,33 @@ def test_csv_tempo_non_crescente(cfg, tmp_path):
(tmp_path / "d.csv").write_text("t_ms,T_C,dT_C\n200,20,0\n100,20,0\n")
with pytest.raises(dati.ErroreDati, match="crescente"):
dati.leggi_csv(tmp_path / "d.csv", cfg)
def test_toml_non_valido(tmp_path):
(tmp_path / "c.toml").write_text("[dati\nrotto")
with pytest.raises(config.ErroreConfig, match="TOML non valido"):
config.leggi(tmp_path / "c.toml")
@pytest.mark.parametrize(("vecchio", "nuovo", "messaggio"), [
('unita_tempo = "ms"', 'unita_tempo = "min"', "unita_tempo"),
('serie_riferimento = "T_C"', 'serie_riferimento = "X"', "serie_riferimento"),
])
def test_valori_non_ammessi(tmp_path, vecchio, nuovo, messaggio):
testo = (RADICE / "config.toml").read_text()
assert vecchio in testo
(tmp_path / "c.toml").write_text(testo.replace(vecchio, nuovo, 1))
with pytest.raises(config.ErroreConfig, match=messaggio):
config.leggi(tmp_path / "c.toml")
def test_csv_senza_righe_di_dati(cfg, tmp_path):
(tmp_path / "d.csv").write_text("t_ms,T_C,dT_C\n")
with pytest.raises(dati.ErroreDati, match="vuoti o non numerici"):
dati.leggi_csv(tmp_path / "d.csv", cfg)
def test_csv_con_valori_non_numerici(cfg, tmp_path):
(tmp_path / "d.csv").write_text("t_ms,T_C,dT_C\n100,abc,0.1\n250,20.1,0.2\n")
with pytest.raises(dati.ErroreDati, match="vuoti o non numerici"):
dati.leggi_csv(tmp_path / "d.csv", cfg)
+15
View File
@@ -94,3 +94,18 @@ def test_salita_complessiva_sotto_soglia_non_e_un_gradino(cfg):
T[101] += 8.0
T[102:] += 16.0 # 16 °C in due campioni: sotto la soglia di 20
assert tipi(t, {"T_C": T, "dT_C": T - 23.0}, cfg) == ["riposo"]
def test_domini_toml_vuoto_rifiutato(sintetico, tmp_path):
t, _ = sintetico
(tmp_path / "d.toml").write_text("# nessun dominio\n")
with pytest.raises(ValueError, match="senza"):
domini.leggi_toml(tmp_path / "d.toml", t)
def test_domini_toml_intervallo_vuoto_rifiutato(sintetico, tmp_path):
t, _ = sintetico
(tmp_path / "d.toml").write_text('[[dominio]]\ntipo="riposo"\nt0_s=0\nt1_s=0\n'
'[[dominio]]\ntipo="raffreddamento"\nt0_s=0\nt1_s=30\n')
with pytest.raises(ValueError, match="vuoto"):
domini.leggi_toml(tmp_path / "d.toml", t)
+9
View File
@@ -180,3 +180,12 @@ def test_salto_con_tratto_adiacente_indeterminato_usa_la_misura_corretta(cfg):
assert g["stima"] == "misura corretta"
assert abs(g["delta"] - ampiezza) <= abs(g["delta_misurato"] - ampiezza) + 1e-9
assert g["delta"] == pytest.approx(ampiezza, rel=0.03)
def test_dati_non_finiti_non_convergono_senza_eccezioni(cfg):
t = np.arange(20) * 0.15
y = 25.0 + np.exp(-t / 5.0)
y[3] = np.nan
for nome in MODELLI:
r = adatta(t, y, nome, 0.1, cfg)
assert r["convergenza"] is False and r["modello"] == nome
+29
View File
@@ -72,3 +72,32 @@ def test_senza_nan():
def test_report_mostra_la_scala_robusta_dei_residui(tmp_path):
report, _ = esegui(tmp_path, [(20.0, 80.0)])
assert r"\hat\sigma_\text{res}" in report and "1.4826" in report
def test_equazione_lineare_con_segno():
from fitseg.uscita import _eq_numerica
fit = {"modello": "lineare", "parametri": {"a": 20.0, "b": -0.5}}
assert _eq_numerica(fit) == r"y = 20 - 0.5\,t'"
assert _eq_numerica({"modello": "lineare", "parametri": {"a": 20.0, "b": 0.25}}) == r"y = 20 + 0.25\,t'"
def test_salto_solo_misurato_nel_report():
from fitseg.uscita import _salto
g = {"n": 3, "durata_s": 0.3, "stima": "misura", "delta": 70.0, "delta_misurato": 70.0}
testo = _salto({"gradino": g})
assert "misurato sui campioni" in testo and "modelli adiacenti non disponibili" in testo and testo.count("$") % 2 == 0
def test_grafici_con_campioni_esclusi_e_modelli_alternativi(tmp_path):
# riposo con deriva (costante, lineare ed esponenziale validi → curve tratteggiate) e scarta_dopo_salto_n > 0 (campioni grigi)
from conftest import RADICE
testo = (RADICE / "config.toml").read_text().replace("scarta_dopo_salto_n = 0", "scarta_dopo_salto_n = 2")
(tmp_path / "c.toml").write_text(testo)
t, serie = segnale(gradini=[(40.0, 70.0)], durata=80.0, rumore=0.3)
deriva = 0.02 * t
serie = {"T_C": serie["T_C"] + deriva, "dT_C": serie["dT_C"] + deriva}
csv = tmp_path / "sint.csv"
scrivi_csv(csv, t, serie)
cli.main(["--config", str(tmp_path / "c.toml"), "--output", str(tmp_path / "out"), "analizza", str(csv)])
cartella = tmp_path / "out/sint/02_sovrapposizione"
assert (cartella / "dominio1_T_C.png").stat().st_size > 0 and (cartella / "dominio3_T_C.png").stat().st_size > 0