Initialize project with basic structure, including Docker configuration, backend and frontend setup, environment configuration, and essential files for development.
This commit is contained in:
97
backend/internal/domain/balancer_test.go
Normal file
97
backend/internal/domain/balancer_test.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBalanceProducesDeterministicFullTeamsAndReserve(t *testing.T) {
|
||||
var players []Player
|
||||
for i := 0; i < 23; i++ {
|
||||
players = append(players, Player{
|
||||
ID: fmt.Sprintf("p%02d", i),
|
||||
Ratings: Ratings{
|
||||
Tank: 5 + i%36,
|
||||
Damage: 5 + (i*3)%36,
|
||||
Support: 5 + (i*7)%36,
|
||||
},
|
||||
})
|
||||
}
|
||||
first, err := Balance("event", players)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, _ := Balance("event", players)
|
||||
if !reflect.DeepEqual(first, second) {
|
||||
t.Fatal("balancer output is not deterministic")
|
||||
}
|
||||
if len(first) != 3 {
|
||||
t.Fatalf("got %d candidates", len(first))
|
||||
}
|
||||
for _, candidate := range first {
|
||||
if len(candidate.Teams) != 4 || len(candidate.Reserve) != 3 {
|
||||
t.Fatalf("unexpected allocation: %d teams, %d reserve", len(candidate.Teams), len(candidate.Reserve))
|
||||
}
|
||||
for _, team := range candidate.Teams {
|
||||
counts := map[Role]int{}
|
||||
for _, slot := range team.Slots {
|
||||
counts[slot.Role]++
|
||||
}
|
||||
if counts[Tank] != 1 || counts[Damage] != 2 || counts[Support] != 2 {
|
||||
t.Fatalf("invalid composition: %#v", counts)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceKeepsOddNumberOfFullTeams(t *testing.T) {
|
||||
players := make([]Player, 15)
|
||||
for i := range players {
|
||||
players[i] = Player{
|
||||
ID: fmt.Sprintf("p%02d", i),
|
||||
Ratings: Ratings{Tank: 10 + i, Damage: 15 + i%20, Support: 8 + (i*3)%30},
|
||||
}
|
||||
}
|
||||
candidates, err := Balance("event", players)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, candidate := range candidates {
|
||||
if len(candidate.Teams) != 3 || len(candidate.Reserve) != 0 {
|
||||
t.Fatalf("expected three full teams, got %d teams and %d reserve", len(candidate.Teams), len(candidate.Reserve))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceUsesSoftRoleAndTeammatePreferences(t *testing.T) {
|
||||
players := make([]Player, 10)
|
||||
for i := range players {
|
||||
players[i] = Player{
|
||||
ID: fmt.Sprintf("p%02d", i),
|
||||
Ratings: Ratings{Tank: 20, Damage: 20, Support: 20},
|
||||
}
|
||||
}
|
||||
players[0].PreferredRoles = []Role{Support}
|
||||
players[0].PreferredPlayerIDs = []string{"p01"}
|
||||
candidates, err := Balance("event", players)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
best := candidates[0]
|
||||
var teamForP0, teamForP1 int = -1, -1
|
||||
var roleForP0 Role
|
||||
for teamIndex, team := range best.Teams {
|
||||
for _, slot := range team.Slots {
|
||||
switch slot.PlayerID {
|
||||
case "p00":
|
||||
teamForP0, roleForP0 = teamIndex, slot.Role
|
||||
case "p01":
|
||||
teamForP1 = teamIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
if teamForP0 != teamForP1 || roleForP0 != Support {
|
||||
t.Fatalf("preferences were not reflected in best candidate: role=%s teams=%d/%d", roleForP0, teamForP0, teamForP1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user