from pathlib import Path from app import main from app.modules.results.service import parse_training_curve def test_parse_yolo_results_curve(tmp_path: Path): csv_path = tmp_path / "results.csv" csv_path.write_text( "\n".join( [ "epoch,time,train/box_loss,train/seg_loss,metrics/mAP50(M),val/seg_loss,lr/pg0", "1,1.0,1.5,3.0,0.12,2.8,0.001", "2,2.0,1.2,2.5,0.18,2.1,0.001", "3,3.0,0.9,2.0,0.25,1.9,0.001", ] ), encoding="utf-8", ) curve = parse_training_curve(csv_path) assert curve is not None assert curve["x_key"] == "epoch" names = [item["name"] for item in curve["series"]] assert "train/seg_loss" in names assert "metrics/mAP50(M)" in names assert all("lr/" not in name for name in names) def test_parse_single_epoch_yolo_results_curve(tmp_path: Path): csv_path = tmp_path / "results.csv" csv_path.write_text( "\n".join( [ "epoch,time,train/box_loss,train/seg_loss,metrics/mAP50(M),lr/pg0", "1,1.0,1.5,3.0,0.12,0.001", ] ), encoding="utf-8", ) curve = parse_training_curve(csv_path) assert curve is not None assert curve["row_count"] == 1 seg_loss = next(item for item in curve["series"] if item["name"] == "train/seg_loss") assert seg_loss["points"] == [{"x": 1.0, "y": 3.0}] def test_results_api_honors_limit(monkeypatch): calls = {} def fake_scan_results(limit: int = 1000): calls["limit"] = limit return [{"name": "a.png", "relative_path": "var/a.png"}] monkeypatch.setattr(main, "scan_results", fake_scan_results) response = main.api_results(limit=123) assert response == [{"name": "a.png", "relative_path": "var/a.png"}] assert calls["limit"] == 123 def test_results_curve_api_honors_limit(monkeypatch): calls = {} def fake_scan_training_curves(limit: int = 100): calls["limit"] = limit return [{"name": "results", "relative_path": "var/results.csv"}] monkeypatch.setattr(main, "scan_training_curves", fake_scan_training_curves) response = main.api_result_curves(limit=77) assert response == [{"name": "results", "relative_path": "var/results.csv"}] assert calls["limit"] == 77