class TestRandomDrawGenerator(unittest.TestCase): """Basic unit test for random draws. Because it's random, you can't really do much to test it.""" teams = [(1, 'A'), (2, 'B'), (3, 'A'), (4, 'B'), (5, 'C'), (6, 'D'), (7, 'E'), (8, 'A'), (9, 'D'), (10, 'E'), (11, 'D'), (12, 'A')] def test_invalid_option(self): teams = [TestTeam(*args, aff_count=0) for args in self.teams] def go(): self.rd = DrawGenerator("random", teams, random=True) self.assertRaises(ValueError, go) def test_draw(self): for i in xrange(100): teams = [TestTeam(*args, aff_count=0) for args in self.teams] self.rd = DrawGenerator("random", teams, avoid_conflicts="on") _draw = self.rd.make_draw() for pairing in _draw: if pairing.aff_team.seen(pairing.neg_team) or \ pairing.neg_team.seen(pairing.aff_team) or \ pairing.aff_team.institution == pairing.neg_team.institution: print pairing self.assertEqual(pairing.flags, ["max_swapped"]) else: self.assertEqual(pairing.flags, [])
class TestEliminationDrawGenerator(unittest.TestCase): team_data = [(1, 'A'), (2, 'B'), (3, 'A'), (4, 'B'), (5, 'C'), (6, 'D'), (7, 'E'), (8, 'A'), (9, 'D'), (10, 'E'), (11, 'D'), (12, 'A')] def setUp(self): self.teams = [TestTeam(*args) for args in self.team_data] def _results(self, *args): _t = lambda id: self.teams[id-1] _p = lambda ids: map(_t, ids) from debate.draw import Pairing pairings = list() for i, (teams, winner) in enumerate(args): pairing = Pairing(_p(teams), 0, i, winner=_t(winner)) pairings.append(pairing) return pairings def _teams(self, *args): _t = lambda id: self.teams[id-1] return map(_t, args) def test_no_bypass(self): teams = list() results = self._results(([1, 5], 1), ([6, 7], 7), ([3, 2], 3), ([4, 8], 8)) self.run_draw(teams, results, [(1, 8), (7, 3)]) def test_bypass(self): teams = self._teams(9, 11, 10, 12) results = self._results(([1, 5], 1), ([6, 7], 7), ([3, 2], 3), ([4, 8], 8)) self.run_draw(teams, results, [(9, 8), (11, 3), (10, 7), (12, 1)]) def test_error(self): teams = self._teams(9, 11, 12) results = self._results(([1, 5], 1), ([6, 7], 7), ([3, 2], 3), ([4, 8], 8)) self.ed = DrawGenerator("elimination", teams, results) self.assertRaises(RuntimeError, self.ed.make_draw) def run_draw(self, teams, results, expected): self.ed = DrawGenerator("elimination", teams, results) pairings = self.ed.make_draw() self.assertEqual([(p.aff_team.id, p.neg_team.id) for p in pairings], expected)
class TestPartialEliminationDrawGenerator(unittest.TestCase): teams = [(1, 'A'), (2, 'B'), (3, 'A'), (4, 'B'), (5, 'C'), (6, 'D'), (7, 'E'), (8, 'A'), (9, 'D'), (10, 'E'), (11, 'D'), (12, 'A')] def test_split(self): self.fed = DrawGenerator("first_elimination", DUMMY_TEAMS) self.assertEqual(self.fed._bypass_debate_split( 3), ( 1, 2)) self.assertEqual(self.fed._bypass_debate_split( 5), ( 3, 2)) self.assertEqual(self.fed._bypass_debate_split( 8), ( 8, 0)) self.assertEqual(self.fed._bypass_debate_split(11), ( 5, 6)) self.assertEqual(self.fed._bypass_debate_split(21), (11, 10)) self.assertEqual(self.fed._bypass_debate_split(24), ( 8, 16)) self.assertEqual(self.fed._bypass_debate_split(31), ( 1, 30)) self.assertEqual(self.fed._bypass_debate_split(32), (32, 0)) del self.fed def test_even_numbers(self): self.run_draw(2, [(1, 2)]) self.run_draw(4, [(1, 4), (2, 3)]) self.run_draw(8, [(1, 8), (2, 7), (3, 6), (4, 5)]) def test_weird_numbers(self): self.run_draw(3, [(2, 3)], [1]) self.run_draw(5, [(4, 5)], [1, 2, 3]) self.run_draw(6, [(3, 6), (4, 5)], [1, 2]) self.run_draw(12, [(5, 12), (6, 11), (7, 10), (8, 9)], [1, 2, 3, 4]) def run_draw(self, break_size, expected, exp_bypassing=None): teams = [TestTeam(*args) for args in self.teams] self.fed = DrawGenerator("first_elimination", teams, break_size=break_size) pairings = self.fed.make_draw() self.assertEqual([(p.aff_team.id, p.neg_team.id) for p in pairings], expected) if exp_bypassing is not None: bypassing = [t.id for t in self.fed.get_bypassing_teams()] self.assertEqual(bypassing, exp_bypassing)
class TestPowerPairedDrawGenerator(unittest.TestCase): """Test the entire draw functions as a black box.""" # Yep, I spent a lot of time constructing this realistic hypothetical # situation with lots of swaps and manually figuring out the anticipated # result. standings = dict() standings[1] = [((12, 'B', 4, [26, 11, 15, 14]), {"aff_count": 2, "allocated_side": "aff"}), (( 2, 'D', 3, [22, 16, 20, 10]), {"aff_count": 2, "allocated_side": "aff"}), (( 3, 'E', 3, [23, 20, 25, 4]), {"aff_count": 2, "allocated_side": "aff"}), ((11, 'B', 3, [ 1, 12, 23, 22]), {"aff_count": 2, "allocated_side": "neg"}), (( 6, 'E', 3, [19, 15, 18, 9]), {"aff_count": 2, "allocated_side": "neg"}), ((17, 'E', 3, [21, 14, 7, 25]), {"aff_count": 2, "allocated_side": "neg"}), (( 4, 'B', 3, [18, 25, 5, 3]), {"aff_count": 3, "allocated_side": "aff"}), ((14, 'A', 3, [24, 17, 9, 12]), {"aff_count": 2, "allocated_side": "aff"}), (( 8, 'A', 3, [15, 24, 1, 15]), {"aff_count": 2, "allocated_side": "neg"}), (( 7, 'D', 2, [16, 9, 17, 16]), {"aff_count": 2, "allocated_side": "aff"}), (( 9, 'D', 2, [ 5, 7, 14, 6]), {"aff_count": 2, "allocated_side": "aff"}), ((15, 'B', 2, [ 8, 6, 12, 8]), {"aff_count": 2, "allocated_side": "neg"}), ((18, 'B', 2, [ 4, 21, 6, 21]), {"aff_count": 2, "allocated_side": "neg"}), ((22, 'A', 2, [ 2, 10, 16, 11]), {"aff_count": 2, "allocated_side": "neg"}), ((23, 'A', 2, [ 3, 19, 11, 5]), {"aff_count": 2, "allocated_side": "aff"}), ((24, 'B', 2, [14, 8, 19, 20]), {"aff_count": 3, "allocated_side": "aff"}), ((25, 'A', 2, [10, 4, 3, 17]), {"aff_count": 3, "allocated_side": "aff"}), (( 1, 'C', 1, [11, 26, 8, 19]), {"aff_count": 2, "allocated_side": "neg"}), (( 5, 'C', 1, [ 9, 13, 4, 23]), {"aff_count": 1, "allocated_side": "neg"}), ((10, 'B', 1, [25, 22, 13, 2]), {"aff_count": 1, "allocated_side": "aff"}), ((16, 'D', 1, [ 7, 2, 22, 7]), {"aff_count": 2, "allocated_side": "neg"}), ((20, 'E', 1, [13, 3, 2, 24]), {"aff_count": 2, "allocated_side": "aff"}), ((21, 'A', 1, [17, 18, 26, 18]), {"aff_count": 2, "allocated_side": "aff"}), ((19, 'B', 1, [ 6, 23, 24, 1]), {"aff_count": 1, "allocated_side": "neg"}), ((26, 'B', 1, [12, 1, 21, 13]), {"aff_count": 2, "allocated_side": "neg"}), ((13, 'C', 0, [20, 5, 10, 26]), {"aff_count": 2, "allocated_side": "neg"})] expected = dict() expected[1] = [dict(odd_bracket="pullup_top", pairing_method="slide", avoid_conflicts="one_up_one_down", side_allocations="balance"), [ (12, 2, ["pullup"], True), ( 3, 14, ["1u1d_hist"], True), (11, 4, ["1u1d_other"], False), ( 6, 7, ["1u1d_other", "pullup"], True), (17, 8, ["1u1d_hist"], True), ( 9, 24, ["1u1d_other"], False), (15, 23, ["1u1d_inst"], True), (18, 25, [], False), (22, 1, ["pullup"], True), ( 5, 19, ["1u1d_other"], True), (10, 21, ["1u1d_inst"], False), (16, 13, ["1u1d_other", "pullup"], True), (20, 26, ["1u1d_hist"], True)]] expected[2] = [dict(odd_bracket="intermediate_bubble_up_down", pairing_method="slide", avoid_conflicts="one_up_one_down", side_allocations="balance"), [ (12, 2, [], True), (3, 17, [], True), # institution conflict, but swapping # would give history conflict (11, 14, ["1u1d_inst"], True), (6, 4, ["1u1d_other"], False), (8, 7, [], True), (9, 22, [], True), (15, 23, [], True), (18, 24, [], False), (1, 25, [], False), (5, 20, [], False), (10, 21, [], False), (16, 26, ["bub_up_hist"], True), (19, 13, ["bub_up_accom"], False)]] expected[3] = [dict(odd_bracket="intermediate1", pairing_method="fold", avoid_conflicts="off", side_allocations="preallocated"), [ (12, 11, [], False), ( 2, 8, [], False), ( 3, 17, [], False), ( 4, 6, [], False), (14, 15, [], False), ( 7, 22, [], False), ( 9, 18, [], False), (23, 16, [], False), (24, 5, [], False), (25, 1, [], False), (10, 26, [], False), (20, 19, [], False), (21, 13, [], False)]] expected[4] = [dict(odd_bracket="intermediate2", pairing_method="fold", avoid_conflicts="off", side_allocations="preallocated"), [ (12, 11, [], False), ( 2, 8, [], False), ( 3, 17, [], False), ( 4, 6, [], False), (14, 15, [], False), ( 7, 22, [], False), ( 9, 18, [], False), (23, 16, [], False), (24, 5, [], False), (25, 1, [], False), (10, 26, [], False), (20, 19, [], False), (21, 13, [], False)]] def do_draw(self, standings, options): standings = [TestTeam(*args, **kwargs) for args, kwargs in standings] self.ppd = DrawGenerator("power_paired", standings, **options) return self.ppd.make_draw() def draw_test(self, standings_key, expected_key): standings = self.standings[standings_key] kwargs, expected = self.expected[expected_key] draw = self.do_draw(standings, kwargs) for actual, (exp_aff, exp_neg, exp_flags, same_affs) in zip(draw, expected): actual_teams = (actual.aff_team.id, actual.neg_team.id) expected_teams = (exp_aff, exp_neg) if same_affs: self.assertItemsEqual(actual_teams, expected_teams) else: self.assertEqual(actual_teams, expected_teams) self.assertEqual(actual.flags, exp_flags) def test_1_1(self): self.draw_test(1, 1) def test_1_2(self): self.draw_test(1, 2) def test_1_3(self): self.draw_test(1, 3) def test_1_4(self): self.draw_test(1, 4)