|
|
|
|
@ -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 |
|
|
|
|
|