"""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 # Component 1 should return "Fiscaal-economisch beleid versus sociaal welzijn en internationale rechten" label1 = get_svd_label(1) assert "Fiscaal-economisch" in label1 or "fiscaal-economisch" in label1.lower() # Component 2 should return "Nationalistische versus multilateralistische oriëntatie" label2 = get_svd_label(2) assert "Nationalistisch" in label2 or "nationalistisch" in label2.lower() # Component 3 should return "Verzorgingsstaat versus defensie en nationale veiligheid" label3 = get_svd_label(3) assert "Verzorgingsstaat" in label3 or "verzorgingsstaat" in label3.lower() def test_compute_flip_direction_right_on_left(): """Test that flip is True when right parties are on the left.""" from analysis.svd_labels import compute_flip_direction # Right parties (PVV, FVD) have negative scores (on left), left parties have positive party_scores = { "PVV": [-0.8, 0.0], # Right party "FVD": [-0.6, 0.0], # Right party "SP": [0.6, 0.0], # Left party "DENK": [0.4, 0.0], # Left party } # Component 1: right_mean = -0.7, left_mean = 0.5 # right_mean < left_mean, so flip = True assert compute_flip_direction(1, party_scores) is True def test_compute_flip_direction_right_on_right(): """Test that flip is False when right parties are already on the right.""" from analysis.svd_labels import compute_flip_direction # Right parties (PVV, FVD) have positive scores (on right), left parties have negative party_scores = { "PVV": [0.8, 0.0], # Right party "FVD": [0.6, 0.0], # Right party "SP": [-0.6, 0.0], # Left party "DENK": [-0.4, 0.0], # Left party } # Component 1: right_mean = 0.7, left_mean = -0.5 # right_mean > left_mean, so flip = False assert compute_flip_direction(1, party_scores) is False def test_compute_flip_direction_insufficient_data(): """Test that flip is False when there's insufficient data.""" from analysis.svd_labels import compute_flip_direction # No right parties in data party_scores = { "SP": [0.6, 0.0], "DENK": [0.4, 0.0], } assert compute_flip_direction(1, party_scores) is False # No left parties in data party_scores = { "VVD": [0.5, 0.0], "PVV": [0.8, 0.0], } assert compute_flip_direction(1, party_scores) is False def test_auto_flip_computation_for_all_components(): """Test that flip directions are computed correctly for all components.""" from analysis.svd_labels import compute_flip_direction # Simulate party scores for 10 components using CANONICAL_RIGHT/LEFT # Right parties should have positive scores on component 1 # Left parties should have negative scores on component 1 party_scores = { "PVV": [0.8] * 10, # Right party (CANONICAL_RIGHT), positive on all "FVD": [0.6] * 10, # Right party (CANONICAL_RIGHT), positive on all "SP": [-0.6] * 10, # Left party (CANONICAL_LEFT), negative on all "DENK": [-0.4] * 10, # Left party (CANONICAL_LEFT), negative on all } # For all components, right_mean > left_mean, so flip should be False for comp in range(1, 11): flip = compute_flip_direction(comp, party_scores) assert flip is False, f"Component {comp} should not flip" # Now test with right parties on left (negative scores) party_scores_left = { "PVV": [-0.8] * 10, # Right party (CANONICAL_RIGHT), negative "FVD": [-0.6] * 10, # Right party (CANONICAL_RIGHT), negative "SP": [0.6] * 10, # Left party (CANONICAL_LEFT), positive "DENK": [0.4] * 10, # Left party (CANONICAL_LEFT), positive } # For all components, right_mean < left_mean, so flip should be True for comp in range(1, 11): flip = compute_flip_direction(comp, party_scores_left) assert flip is True, f"Component {comp} should flip"