mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-10 14:16:47 -04:00
Refactor playoff bracket logic to more easily support alternative formats.
This commit is contained in:
171
bracket/bracket_test.go
Normal file
171
bracket/bracket_test.go
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright 2022 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package bracket
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena-lite/model"
|
||||
"github.com/Team254/cheesy-arena-lite/tournament"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNewBracketErrors(t *testing.T) {
|
||||
_, err := newBracket([]matchupTemplate{}, 8)
|
||||
if assert.NotNil(t, err) {
|
||||
assert.Equal(t, "could not find template for matchup {round:1 group:1} in the list of templates", err.Error())
|
||||
}
|
||||
|
||||
matchTemplate := matchupTemplate{
|
||||
matchupKey: newMatchupKey(1, 1),
|
||||
redAllianceSource: allianceSource{allianceId: 1},
|
||||
blueAllianceSource: newMatchupAllianceSource(2, 2),
|
||||
}
|
||||
_, err = newBracket([]matchupTemplate{matchTemplate}, 8)
|
||||
if assert.NotNil(t, err) {
|
||||
assert.Equal(t, "both alliances must be populated either from selection or a lower round", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewBracketInverseSeeding(t *testing.T) {
|
||||
database := setupTestDb(t)
|
||||
matchupTemplates := []matchupTemplate{
|
||||
{
|
||||
matchupKey: newMatchupKey(1, 1),
|
||||
displayNameFormat: "F-${instance}",
|
||||
numWinsToAdvance: 2,
|
||||
redAllianceSource: newMatchupAllianceSource(2, 1),
|
||||
blueAllianceSource: newMatchupAllianceSource(2, 2),
|
||||
},
|
||||
{
|
||||
matchupKey: newMatchupKey(2, 1),
|
||||
displayNameFormat: "SF${group}-${instance}",
|
||||
numWinsToAdvance: 2,
|
||||
redAllianceSource: newMatchupAllianceSource(4, 2),
|
||||
blueAllianceSource: newMatchupAllianceSource(4, 1),
|
||||
},
|
||||
{
|
||||
matchupKey: newMatchupKey(2, 2),
|
||||
displayNameFormat: "SF${group}-${instance}",
|
||||
numWinsToAdvance: 2,
|
||||
redAllianceSource: allianceSource{allianceId: 3},
|
||||
blueAllianceSource: allianceSource{allianceId: 2},
|
||||
},
|
||||
{
|
||||
matchupKey: newMatchupKey(4, 1),
|
||||
displayNameFormat: "SF${group}-${instance}",
|
||||
numWinsToAdvance: 2,
|
||||
redAllianceSource: allianceSource{allianceId: 8},
|
||||
blueAllianceSource: allianceSource{allianceId: 1},
|
||||
},
|
||||
{
|
||||
matchupKey: newMatchupKey(4, 2),
|
||||
displayNameFormat: "SF${group}-${instance}",
|
||||
numWinsToAdvance: 2,
|
||||
redAllianceSource: allianceSource{allianceId: 5},
|
||||
blueAllianceSource: allianceSource{allianceId: 4},
|
||||
},
|
||||
}
|
||||
|
||||
tournament.CreateTestAlliances(database, 2)
|
||||
bracket, err := newBracket(matchupTemplates, 2)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, bracket.Update(database, &dummyStartTime))
|
||||
matches, err := database.GetMatchesByType("elimination")
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 2, len(matches)) {
|
||||
assertMatch(t, matches[0], "F-1", 1, 2)
|
||||
assertMatch(t, matches[1], "F-2", 1, 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBracketUpdateTiming(t *testing.T) {
|
||||
database := setupTestDb(t)
|
||||
|
||||
tournament.CreateTestAlliances(database, 4)
|
||||
bracket, err := NewSingleEliminationBracket(4)
|
||||
assert.Nil(t, err)
|
||||
startTime := time.Unix(1000, 0)
|
||||
assert.Nil(t, bracket.Update(database, &startTime))
|
||||
matches, err := database.GetMatchesByType("elimination")
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 4, len(matches)) {
|
||||
assert.Equal(t, int64(1000), matches[0].Time.Unix())
|
||||
assert.Equal(t, int64(1600), matches[1].Time.Unix())
|
||||
assert.Equal(t, int64(2200), matches[2].Time.Unix())
|
||||
assert.Equal(t, int64(2800), matches[3].Time.Unix())
|
||||
}
|
||||
scoreMatch(database, "SF1-1", model.RedWonMatch)
|
||||
scoreMatch(database, "SF1-2", model.BlueWonMatch)
|
||||
startTime = time.Unix(5000, 0)
|
||||
assert.Nil(t, bracket.Update(database, &startTime))
|
||||
matches, err = database.GetMatchesByType("elimination")
|
||||
assert.Nil(t, err)
|
||||
if assert.Equal(t, 5, len(matches)) {
|
||||
assert.Equal(t, int64(1000), matches[0].Time.Unix())
|
||||
assert.Equal(t, int64(5000), matches[1].Time.Unix())
|
||||
assert.Equal(t, int64(2200), matches[2].Time.Unix())
|
||||
assert.Equal(t, int64(5600), matches[3].Time.Unix())
|
||||
assert.Equal(t, int64(6200), matches[4].Time.Unix())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBracketUpdateTeamPositions(t *testing.T) {
|
||||
database := setupTestDb(t)
|
||||
|
||||
tournament.CreateTestAlliances(database, 4)
|
||||
bracket, err := NewSingleEliminationBracket(4)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, bracket.Update(database, &dummyStartTime))
|
||||
matches, _ := database.GetMatchesByType("elimination")
|
||||
match1 := matches[0]
|
||||
match2 := matches[1]
|
||||
assert.Equal(t, 102, match1.Red1)
|
||||
assert.Equal(t, 101, match1.Red2)
|
||||
assert.Equal(t, 103, match1.Red3)
|
||||
assert.Equal(t, 302, match2.Blue1)
|
||||
assert.Equal(t, 301, match2.Blue2)
|
||||
assert.Equal(t, 303, match2.Blue3)
|
||||
|
||||
// Shuffle the team positions and check that the subsequent matches in the same round have the same ones.
|
||||
match1.Red1, match1.Red2 = match1.Red2, 104
|
||||
match2.Blue1, match2.Blue3 = 305, match2.Blue1
|
||||
database.UpdateMatch(&match1)
|
||||
database.UpdateMatch(&match2)
|
||||
scoreMatch(database, "SF1-1", model.RedWonMatch)
|
||||
scoreMatch(database, "SF2-1", model.BlueWonMatch)
|
||||
assert.Nil(t, bracket.Update(database, &dummyStartTime))
|
||||
matches, _ = database.GetMatchesByType("elimination")
|
||||
if assert.Equal(t, 4, len(matches)) {
|
||||
assert.Equal(t, match1.Red1, matches[0].Red1)
|
||||
assert.Equal(t, match1.Red2, matches[0].Red2)
|
||||
assert.Equal(t, match1.Red3, matches[0].Red3)
|
||||
assert.Equal(t, match1.Red1, matches[2].Red1)
|
||||
assert.Equal(t, match1.Red2, matches[2].Red2)
|
||||
assert.Equal(t, match1.Red3, matches[2].Red3)
|
||||
|
||||
assert.Equal(t, match2.Blue1, matches[1].Blue1)
|
||||
assert.Equal(t, match2.Blue2, matches[1].Blue2)
|
||||
assert.Equal(t, match2.Blue3, matches[1].Blue3)
|
||||
assert.Equal(t, match2.Blue1, matches[3].Blue1)
|
||||
assert.Equal(t, match2.Blue2, matches[3].Blue2)
|
||||
assert.Equal(t, match2.Blue3, matches[3].Blue3)
|
||||
}
|
||||
|
||||
// Advance them to the finals and verify that the team position updates have been propagated.
|
||||
scoreMatch(database, "SF1-2", model.RedWonMatch)
|
||||
scoreMatch(database, "SF2-2", model.BlueWonMatch)
|
||||
assert.Nil(t, bracket.Update(database, &dummyStartTime))
|
||||
matches, _ = database.GetMatchesByType("elimination")
|
||||
if assert.Equal(t, 6, len(matches)) {
|
||||
for i := 4; i < 6; i++ {
|
||||
assert.Equal(t, match1.Red1, matches[i].Red1)
|
||||
assert.Equal(t, match1.Red2, matches[i].Red2)
|
||||
assert.Equal(t, match1.Red3, matches[i].Red3)
|
||||
assert.Equal(t, match2.Blue1, matches[i].Blue1)
|
||||
assert.Equal(t, match2.Blue2, matches[i].Blue2)
|
||||
assert.Equal(t, match2.Blue3, matches[i].Blue3)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user