File size: 2,299 Bytes
e40dce0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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'}