Spaces:
Paused
Paused
| import random | |
| import types | |
| import importlib | |
| # Import app module once to avoid re-declaring ORM tables across tests | |
| APP_MOD = importlib.import_module('policy_survey_biases.__init__') | |
| def _make_stub_players(n): | |
| class StubParticipant: | |
| def __init__(self, pid): | |
| self.id_in_session = pid | |
| self.vars = {} | |
| class StubPlayer: | |
| def __init__(self, pid): | |
| self.participant = StubParticipant(pid) | |
| self.order_a = None | |
| self.order_b = None | |
| self.order_c = None | |
| def field_maybe_none(self, name): | |
| return getattr(self, name, None) | |
| return [StubPlayer(i + 1) for i in range(n)] | |
| class StubSubsession: | |
| def __init__(self, n): | |
| self._players = _make_stub_players(n) | |
| def get_players(self): | |
| return self._players | |
| def _assign_once(n): | |
| subsession = StubSubsession(n) | |
| # Call the app's method directly with our stub — Python only needs duck-typing | |
| APP_MOD.Subsession.creating_session(subsession) | |
| players = subsession.get_players() | |
| a = [p.order_a for p in players] | |
| b = [p.order_b for p in players] | |
| c = [p.order_c for p in players] | |
| return a, b, c | |
| def test_balanced_assignment_single_session(): | |
| for n in (2, 3, 6, 7): | |
| a, b, c = _assign_once(n) | |
| # Each binary assignment should be as even as possible (difference <= 1) | |
| for arr in (a, b, c): | |
| counts = {v: arr.count(v) for v in set(arr)} | |
| if len(counts) == 2: | |
| diff = abs(list(counts.values())[0] - list(counts.values())[1]) | |
| assert diff <= 1, (n, arr, counts) | |
| else: | |
| # Degenerate case n==1 or all same — not expected here | |
| assert n <= 1, (n, arr, counts) | |
| def test_variation_across_sessions(): | |
| random.seed() # ensure non-deterministic shuffles across runs | |
| seen_a = set() | |
| seen_b = set() | |
| seen_c = set() | |
| n = 6 | |
| # Run multiple times to detect shuffling variation | |
| for _ in range(10): | |
| a, b, c = _assign_once(n) | |
| seen_a.update(a) | |
| seen_b.update(b) | |
| seen_c.update(c) | |
| assert seen_a == {'info_before', 'info_after'} | |
| assert seen_b == {'support_first', 'eval_first'} | |
| assert seen_c == {'recall_first', 'opinion_first'} | |