def test_progress_tournament_active_with_no_active_stages_raises_error( self, db): tournament: Tournament = TournamentFactory( status=Tournament.TournamentStatus.ACTIVE) stages: List[Stage] = [ StageFactory(tournament=tournament, status=Stage.StageStatus.PENDING, ordinal=0), StageFactory(tournament=tournament, status=Stage.StageStatus.PENDING, ordinal=1), StageFactory(tournament=tournament, status=Stage.StageStatus.PENDING, ordinal=2), ] with pytest.raises(TournamentError): tournament.progress(db, autocommit=True) # Make sure the tournament status is unchanged assert tournament.status == Tournament.TournamentStatus.ACTIVE # Make sure the stage statuses are unchanged assert {stage.status for stage in stages} == {Stage.StageStatus.PENDING}
def test_all_matches_complete_all_matches_complete_returns_true(self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(3, tournament=stage.tournament) stage.progress(db, autocommit=True) db.query(Match).update({Match.status: Match.MatchStatus.COMPLETE}) assert stage.all_matches_complete()
def test_progress_tournament_active_on_final_stage_completes_it_and_sets_status_to_complete( self, db): tournament: Tournament = TournamentFactory( status=Tournament.TournamentStatus.ACTIVE) stages: List[Stage] = [ StageFactory( tournament=tournament, status=Stage.StageStatus.COMPLETE if idx < 2 else Stage.StageStatus.PENDING, ordinal=idx, params={'minimum_pool_size': 2}, ) for idx in range(3) ] CompetitorFactory.create_batch(2, tournament=tournament) stages[2].progress(db, autocommit=True) db.query(Match).filter(Match.pool == stages[2].pools[0]).update( {Match.status: Match.MatchStatus.COMPLETE}) tournament.progress(db, autocommit=True) # Verify that the tournament is now complete assert tournament.status == Tournament.TournamentStatus.COMPLETE # Verify that all stages are complete for stage in stages: assert stage.status == Stage.StageStatus.COMPLETE
def test_progress_complete_raises_error(self, db): stage: Stage = StageFactory(status=Stage.StageStatus.COMPLETE) with pytest.raises(TournamentError): stage.progress(db, autocommit=True) # Verify that the status was not altered assert stage.status == Stage.StageStatus.COMPLETE
def test_progress_active_with_unfinished_matches_raises_error(self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(2, tournament=stage.tournament) stage.progress( db, autocommit=True ) # The other tests verify that this will work, so I feel ok using it here with pytest.raises(TournamentError): stage.progress(db, autocommit=True)
def test_all_matches_complete_some_matches_complete_returns_false( self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(3, tournament=stage.tournament) stage.progress(db, autocommit=True) stage.pools[0].matches[0].status = Match.MatchStatus.COMPLETE db.add(stage.pools[0].matches[0]) db.commit() assert not stage.all_matches_complete()
def test_non_pending_stages_raise_errors(self, db): stage: Stage = StageFactory(status=Stage.StageStatus.ACTIVE) CompetitorFactory.create_batch(10, tournament=stage.tournament) with pytest.raises(ValueError): PoolMatchGenerator(stage) # Make sure no pools or matches were created assert len(db.query(Pool).all()) == 0 assert len(db.query(Match).all()) == 0
def test_invalid_configuration_raises_error(self, db): stage: Stage = StageFactory(params={}) CompetitorFactory.create_batch(3, tournament=stage.tournament) pmg = PoolMatchGenerator(stage) with pytest.raises(ValueError): pmg.generate_matches(db, autocommit=True) # Make sure no pools or matches were created assert len(db.query(Pool).all()) == 0 assert len(db.query(Match).all()) == 0
def test_too_few_competitors_for_minimum_pool_size_raises_error(self, db): stage: Stage = StageFactory() CompetitorFactory.create_batch(3, tournament=stage.tournament) pmg = PoolMatchGenerator(stage) with pytest.raises(ValueError): pmg.generate_matches(db, autocommit=True) # Make sure no pools or matches were created assert len(db.query(Pool).all()) == 0 assert len(db.query(Match).all()) == 0
def test_progress_active_and_all_matches_complete_set_to_complete( self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(2, tournament=stage.tournament) stage.progress( db, autocommit=True ) # The other tests verify that this will work, so I feel ok using it here # Mark all the matches as complete db.query(Match).update({Match.status: Match.MatchStatus.COMPLETE}) stage.progress(db, autocommit=True) assert stage.status == Stage.StageStatus.COMPLETE
def test_progress_pending_generate_matches_and_set_to_active(self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(2, tournament=stage.tournament) stage.progress(db, autocommit=True) # Verify that the status was updated assert stage.status == Stage.StageStatus.ACTIVE # Verify that pools and matches were generated assert len(stage.pools) == 1 assert len(stage.pools[0].matches) == 1 assert stage.pools[0].matches[0].status == Match.MatchStatus.PENDING
def test_progress_tournament_ready_starts_first_stage_and_sets_status_to_active( self, db): stage: Stage = StageFactory( params={'minimum_pool_size': 2}, tournament__status=Tournament.TournamentStatus.READY) tournament: Tournament = stage.tournament CompetitorFactory.create_batch(2, tournament=tournament) tournament.progress(db, autocommit=True) # Verify the first stage is active and has pools/matches assert stage.status == Stage.StageStatus.ACTIVE assert len(stage.pools) == 1 assert len(stage.pools[0].matches) == 1 # Verify the tournament is active assert tournament.status == Tournament.TournamentStatus.ACTIVE
def test_enough_competitors_for_one_pool(self, db): stage: Stage = StageFactory() competitors: Sequence[Competitor] = CompetitorFactory.create_batch( 5, tournament=stage.tournament) pmg = PoolMatchGenerator(stage) pmg.generate_matches(db, autocommit=True) # Make sure one pool was created with 10 matches, one for each combination of competitors assert len(stage.pools) == 1 assert stage.pools[0].ordinal == 0 expected_competitor_id_pairs = self._generate_match_combinations( competitors) assert len(stage.pools[0].matches) == len(expected_competitor_id_pairs) actual_competitor_id_pairs = self._get_competitor_id_pairs( stage.pools[0]) assert actual_competitor_id_pairs == expected_competitor_id_pairs # Make sure the ordinals are an in order range from 0 to num matches actual_ordinals = [match.ordinal for match in stage.pools[0].matches] assert actual_ordinals == list(range(len(stage.pools[0].matches)))
def test_enough_competitors_for_many_pools(self, db): stage: Stage = StageFactory() CompetitorFactory.create_batch(17, tournament=stage.tournament) pmg = PoolMatchGenerator(stage) pmg.generate_matches(db, autocommit=True) # Make sure three pools were created, with 6, 6, and 5 competitors, respectively assert len(stage.pools) == 3 def verify_matches(pool: Pool, expected_num_competitors: int): p_competitors = set() for m in pool.matches: p_competitors.add(m.competitor_1) p_competitors.add(m.competitor_2) assert len(p_competitors) == expected_num_competitors expected_competitor_id_pairs = self._generate_match_combinations( list(p_competitors)) assert len(pool.matches) == len(expected_competitor_id_pairs) actual_competitor_id_pairs = self._get_competitor_id_pairs(pool) assert actual_competitor_id_pairs == expected_competitor_id_pairs assert stage.pools[0].ordinal == 0 verify_matches(stage.pools[0], 6) assert stage.pools[1].ordinal == 1 verify_matches(stage.pools[1], 6) assert stage.pools[2].ordinal == 2 verify_matches(stage.pools[2], 5) # Verify that the ordinals are an in order range from 0 to num matches actual_ordinals = [ match.ordinal for pool in stage.pools for match in pool.matches ] assert actual_ordinals == list(range(40))
def test_progress_tournament_active_progresses_the_active_stage_and_starts_the_next_one( self, db): tournament: Tournament = TournamentFactory( status=Tournament.TournamentStatus.ACTIVE) stages: List[Stage] = [ StageFactory( tournament=tournament, status=Stage.StageStatus.PENDING, ordinal=idx, params={'minimum_pool_size': 2}, ) for idx in range(3) ] CompetitorFactory.create_batch(2, tournament=tournament) # Start the first stage and finish all of its matches stages[0].progress(db, autocommit=True) db.query(Match).filter(Match.pool == stages[0].pools[0]).update( {Match.status: Match.MatchStatus.COMPLETE}) tournament.progress(db, autocommit=True) # Verify that the tournament is still active assert tournament.status == Tournament.TournamentStatus.ACTIVE # Verify that the first stage is complete assert stages[0].status == Stage.StageStatus.COMPLETE # Verify that the second stage is active and has pools/matches assert stages[1].status == Stage.StageStatus.ACTIVE assert len(stages[1].pools) == 1 assert len(stages[1].pools[0].matches) == 1 assert stages[1].pools[0].matches[ 0].status == Match.MatchStatus.PENDING # Verify that the third stage is still pending assert stages[2].status == Stage.StageStatus.PENDING
def test_all_matches_complete_no_matches_raises_exception(self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(2, tournament=stage.tournament) with pytest.raises(TournamentError): stage.all_matches_complete()
def test_all_matches_complete_no_matches_complete_returns_false(self, db): stage: Stage = StageFactory(params={'minimum_pool_size': 2}) CompetitorFactory.create_batch(2, tournament=stage.tournament) stage.progress(db, autocommit=True) assert not stage.all_matches_complete()
def test_get_match_generator_double_bracket_stage_type_returns_correctly( self, db): stage: Stage = StageFactory( type=Stage.StageType.BRACKET_DOUBLE_ELIMINATION) mg = MatchGenerator.get_match_generator(stage) assert isinstance(mg, DoubleEliminationBracketMatchGenerator)
def test_get_match_generator_pool_stage_type_returns_correctly(self, db): stage: Stage = StageFactory(type=Stage.StageType.POOL) mg = MatchGenerator.get_match_generator(stage) assert isinstance(mg, PoolMatchGenerator)
def test_get_match_generator_invalid_stage_type_raises_error(self, db): stage: Stage = StageFactory() stage.type = -1 with pytest.raises(ValueError): MatchGenerator.get_match_generator(stage)