From f775e41c96fb322f3de2469e811b84fd9cec5c48 Mon Sep 17 00:00:00 2001 From: Sven Geboers Date: Sun, 5 Apr 2026 02:04:31 +0200 Subject: [PATCH] test: add canonical party set validation for SVD flip direction --- tests/test_svd_labels.py | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tests/test_svd_labels.py b/tests/test_svd_labels.py index 83c723c..ef5059c 100644 --- a/tests/test_svd_labels.py +++ b/tests/test_svd_labels.py @@ -1,6 +1,79 @@ """Tests for analysis/svd_labels module.""" +def test_canonical_party_sets_contain_expected_parties(): + """Verify CANONICAL_RIGHT and CANONICAL_LEFT contain the expected parties.""" + from analysis.config import CANONICAL_LEFT, CANONICAL_RIGHT + + assert "PVV" in CANONICAL_RIGHT + assert "FVD" in CANONICAL_RIGHT + assert "JA21" in CANONICAL_RIGHT + assert "SGP" in CANONICAL_RIGHT + + assert "SP" in CANONICAL_LEFT + assert "PvdA" in CANONICAL_LEFT + assert "PvdD" in CANONICAL_LEFT + assert "DENK" in CANONICAL_LEFT + assert "Volt" in CANONICAL_LEFT + + +def test_compute_flip_direction_uses_all_canonical_right_parties(): + """Test that flip computation correctly uses all four canonical right parties.""" + from analysis.config import CANONICAL_LEFT, CANONICAL_RIGHT + from analysis.svd_labels import compute_flip_direction + + # Build party scores where ALL canonical right parties are on the left (negative) + # and ALL canonical left parties are on the right (positive) + party_scores = {} + for party in CANONICAL_RIGHT: + party_scores[party] = [-0.5] + for party in CANONICAL_LEFT: + party_scores[party] = [0.5] + + # All right parties on left → should flip + assert compute_flip_direction(1, party_scores) is True + + # Invert: all right parties on right (positive), left parties on left (negative) + party_scores_inverted = {} + for party in CANONICAL_RIGHT: + party_scores_inverted[party] = [0.5] + for party in CANONICAL_LEFT: + party_scores_inverted[party] = [-0.5] + + # All right parties on right → should not flip + assert compute_flip_direction(1, party_scores_inverted) is False + + +def test_compute_flip_direction_all_components_canonical_parties(): + """Test flip for all 10 components using full canonical party sets.""" + from analysis.config import CANONICAL_LEFT, CANONICAL_RIGHT + from analysis.svd_labels import compute_flip_direction + + # Right parties on left (negative), left parties on right (positive) + party_scores = {} + for party in CANONICAL_RIGHT: + party_scores[party] = [-0.7] * 10 + for party in CANONICAL_LEFT: + party_scores[party] = [0.3] * 10 + + for comp in range(1, 11): + flip = compute_flip_direction(comp, party_scores) + assert flip is True, f"Component {comp} should flip (right parties on left)" + + # Inverted: right on right, left on left + party_scores_inverted = {} + for party in CANONICAL_RIGHT: + party_scores_inverted[party] = [0.7] * 10 + for party in CANONICAL_LEFT: + party_scores_inverted[party] = [-0.3] * 10 + + for comp in range(1, 11): + flip = compute_flip_direction(comp, party_scores_inverted) + assert flip is False, ( + f"Component {comp} should not flip (right parties on right)" + ) + + def test_get_svd_label_returns_correct_label(): """Test that get_svd_label returns the correct label for each component.""" from analysis.svd_labels import get_svd_label