This is an automated email from the ASF dual-hosted git repository.

Gerrrr pushed a commit to branch multiple-algorithms-single-point
in repository https://gitbox.apache.org/repos/asf/otava-playground.git

commit 55cfb5572ce1f7fb493b138a2475538afa6f9e8b
Author: Alex Sorokoumov <[email protected]>
AuthorDate: Sun Jul 5 10:47:32 2026 -0700

    Expose compare API detection details
    
    Return per-detection change point stats from /api/compare results and cover 
the response shape with an API test.
---
 src/otava_test_data/tests/test_compare_api.py | 26 ++++++++++++++++++++++++++
 src/otava_test_data/web/main.py               |  6 +++++-
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/otava_test_data/tests/test_compare_api.py 
b/src/otava_test_data/tests/test_compare_api.py
index ff84289..dc869e6 100644
--- a/src/otava_test_data/tests/test_compare_api.py
+++ b/src/otava_test_data/tests/test_compare_api.py
@@ -17,6 +17,7 @@
 
 """Tests for the /api/datasets and /api/compare endpoints."""
 
+import pytest
 from fastapi.testclient import TestClient
 
 from otava_test_data.web.main import app
@@ -209,3 +210,28 @@ def test_detect_accepts_otava_algorithm():
     )
     assert r.status_code == 200
     assert r.json()["parameters"]["algorithm"] == "orig"
+
+
+def test_compare_returns_per_detection_details():
+    """`/api/compare` results must carry per-detection stats so the frontend 
can
+    render the detected-change-points table without a second API call."""
+    series = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 
5.0]
+    r = client.post(
+        "/api/compare",
+        json={"data": series, "algorithms": ["split"]},
+    )
+    assert r.status_code == 200
+    split = r.json()["results"]["split"]
+    assert split["indices"] == [7]
+    # New fields required by the per-algorithm detected table:
+    assert "change_points" in split
+    assert len(split["change_points"]) == 1
+    cp = split["change_points"][0]
+    assert cp["index"] == 7
+    for k in ("mean_before", "mean_after", "pvalue"):
+        assert k in cp, f"missing {k} in {cp}"
+        assert isinstance(cp[k], float)
+    # Value checks: the step series [1.0]*7 + [5.0]*7 has clear segment means.
+    assert cp["mean_before"] == pytest.approx(1.0, abs=0.01)
+    assert cp["mean_after"] == pytest.approx(5.0, abs=0.01)
+    assert 0.0 <= cp["pvalue"] <= 1.0
diff --git a/src/otava_test_data/web/main.py b/src/otava_test_data/web/main.py
index 1e5159d..0b8ec55 100644
--- a/src/otava_test_data/web/main.py
+++ b/src/otava_test_data/web/main.py
@@ -1761,7 +1761,11 @@ def _run_algorithm(name: str, data, window_len: int, 
max_pvalue: float,
         min_magnitude=min_magnitude,
         algorithm=name,
     )
-    out = {"indices": res.get("detected_indices", []), "count": 
res.get("count", 0)}
+    out = {
+        "indices": res.get("detected_indices", []),
+        "count": res.get("count", 0),
+        "change_points": res.get("detected_change_points", []),
+    }
     if res.get("error"):
         out["error"] = res["error"]
     return out

Reply via email to