diff --git a/db/migrations/20140524180123_CreateMatches.sql b/db/migrations/20140524180123_CreateMatches.sql index 9fefbbb..5cf948f 100644 --- a/db/migrations/20140524180123_CreateMatches.sql +++ b/db/migrations/20140524180123_CreateMatches.sql @@ -21,10 +21,9 @@ CREATE TABLE matches ( blue2issurrogate bool, blue3 int, blue3issurrogate bool, - status VARCHAR(16), startedat DATETIME, scorecommittedat DATETIME, - winner VARCHAR(16) + status VARCHAR(16) ); CREATE UNIQUE INDEX type_displayname ON matches(type, displayname); diff --git a/field/arena.go b/field/arena.go index 5934908..1e8f82d 100644 --- a/field/arena.go +++ b/field/arena.go @@ -586,7 +586,7 @@ func (arena *Arena) getNextMatch(excludeCurrent bool) (*model.Match, error) { return nil, err } for _, match := range matches { - if match.Status != "complete" && !(excludeCurrent && match.Id == arena.CurrentMatch.Id) { + if !match.IsComplete() && !(excludeCurrent && match.Id == arena.CurrentMatch.Id) { return &match, nil } } @@ -882,7 +882,7 @@ func (arena *Arena) getEventStatusMessage() string { // Only practice and qualification matches have a strict schedule. return "" } - if currentMatch.Status == "complete" { + if currentMatch.IsComplete() { // This is a replay or otherwise unpredictable situation. return "" } diff --git a/field/arena_notifiers.go b/field/arena_notifiers.go index fc60cfe..fa10614 100644 --- a/field/arena_notifiers.go +++ b/field/arena_notifiers.go @@ -179,9 +179,9 @@ func (arena *Arena) generateScorePostedMessage() interface{} { matches, _ := arena.Database.GetMatchesByElimRoundGroup(arena.SavedMatch.ElimRound, arena.SavedMatch.ElimGroup) var redWins, blueWins int for _, match := range matches { - if match.Winner == "R" { + if match.Status == model.RedWonMatch { redWins++ - } else if match.Winner == "B" { + } else if match.Status == model.BlueWonMatch { blueWins++ } } diff --git a/field/arena_test.go b/field/arena_test.go index ae75861..59c45d9 100644 --- a/field/arena_test.go +++ b/field/arena_test.go @@ -377,12 +377,12 @@ func TestLoadNextMatch(t *testing.T) { arena.Database.CreateTeam(&model.Team{Id: 1114}) practiceMatch1 := model.Match{Type: "practice", DisplayName: "1"} - practiceMatch2 := model.Match{Type: "practice", DisplayName: "2", Status: "complete"} + practiceMatch2 := model.Match{Type: "practice", DisplayName: "2", Status: model.RedWonMatch} practiceMatch3 := model.Match{Type: "practice", DisplayName: "3"} arena.Database.CreateMatch(&practiceMatch1) arena.Database.CreateMatch(&practiceMatch2) arena.Database.CreateMatch(&practiceMatch3) - qualificationMatch1 := model.Match{Type: "qualification", DisplayName: "1", Status: "complete"} + qualificationMatch1 := model.Match{Type: "qualification", DisplayName: "1", Status: model.BlueWonMatch} qualificationMatch2 := model.Match{Type: "qualification", DisplayName: "2"} arena.Database.CreateMatch(&qualificationMatch1) arena.Database.CreateMatch(&qualificationMatch2) @@ -391,12 +391,12 @@ func TestLoadNextMatch(t *testing.T) { assert.Equal(t, 0, arena.CurrentMatch.Id) err := arena.SubstituteTeam(1114, "R1") assert.Nil(t, err) - arena.CurrentMatch.Status = "complete" + arena.CurrentMatch.Status = model.TieMatch err = arena.LoadNextMatch() assert.Nil(t, err) assert.Equal(t, 0, arena.CurrentMatch.Id) assert.Equal(t, 0, arena.CurrentMatch.Red1) - assert.NotEqual(t, "complete", arena.CurrentMatch.Status) + assert.Equal(t, false, arena.CurrentMatch.IsComplete()) // Other matches should be loaded by type until they're all complete. err = arena.LoadMatch(&practiceMatch2) @@ -404,12 +404,12 @@ func TestLoadNextMatch(t *testing.T) { err = arena.LoadNextMatch() assert.Nil(t, err) assert.Equal(t, practiceMatch1.Id, arena.CurrentMatch.Id) - practiceMatch1.Status = "complete" + practiceMatch1.Status = model.RedWonMatch arena.Database.SaveMatch(&practiceMatch1) err = arena.LoadNextMatch() assert.Nil(t, err) assert.Equal(t, practiceMatch3.Id, arena.CurrentMatch.Id) - practiceMatch3.Status = "complete" + practiceMatch3.Status = model.BlueWonMatch arena.Database.SaveMatch(&practiceMatch3) err = arena.LoadNextMatch() assert.Nil(t, err) @@ -735,9 +735,9 @@ func setMatch(database *model.Database, match *model.Match, matchTime time.Time, match.Time = matchTime match.StartedAt = startedAt if isComplete { - match.Status = "complete" + match.Status = model.TieMatch } else { - match.Status = "" + match.Status = model.MatchNotPlayed } _ = database.SaveMatch(match) } diff --git a/model/match.go b/model/match.go index 2fb0653..43e1cab 100644 --- a/model/match.go +++ b/model/match.go @@ -33,12 +33,20 @@ type Match struct { Blue2IsSurrogate bool Blue3 int Blue3IsSurrogate bool - Status string StartedAt time.Time ScoreCommittedAt time.Time - Winner string + Status MatchStatus } +type MatchStatus string + +const ( + RedWonMatch MatchStatus = "R" + BlueWonMatch MatchStatus = "B" + TieMatch MatchStatus = "T" + MatchNotPlayed MatchStatus = "" +) + var ElimRoundNames = map[int]string{1: "F", 2: "SF", 4: "QF", 8: "EF"} func (database *Database) CreateMatch(match *Match) error { @@ -96,6 +104,10 @@ func (database *Database) GetMatchesByType(matchType string) ([]Match, error) { return matches, err } +func (match *Match) IsComplete() bool { + return match.Status != MatchNotPlayed +} + func (match *Match) CapitalizedType() string { if match.Type == "" { return "" diff --git a/model/match_test.go b/model/match_test.go index e9d3304..0971ffd 100644 --- a/model/match_test.go +++ b/model/match_test.go @@ -21,7 +21,7 @@ func TestMatchCrud(t *testing.T) { db := setupTestDb(t) match := Match{0, "qualification", "254", time.Now().UTC(), 0, 0, 0, 0, 0, 1, false, 2, false, 3, false, 4, false, - 5, false, 6, false, "", time.Now().UTC(), time.Now().UTC(), ""} + 5, false, 6, false, time.Now().UTC(), time.Now().UTC(), MatchNotPlayed} db.CreateMatch(&match) match2, err := db.GetMatchById(1) assert.Nil(t, err) @@ -30,7 +30,7 @@ func TestMatchCrud(t *testing.T) { assert.Nil(t, err) assert.Equal(t, match, *match3) - match.Status = "started" + match.Status = RedWonMatch db.SaveMatch(&match) match2, err = db.GetMatchById(1) assert.Nil(t, err) @@ -46,7 +46,7 @@ func TestTruncateMatches(t *testing.T) { db := setupTestDb(t) match := Match{0, "qualification", "254", time.Now().UTC(), 0, 0, 0, 0, 0, 1, false, 2, false, 3, false, 4, false, - 5, false, 6, false, "", time.Now().UTC(), time.Now().UTC(), ""} + 5, false, 6, false, time.Now().UTC(), time.Now().UTC(), MatchNotPlayed} db.CreateMatch(&match) db.TruncateMatches() match2, err := db.GetMatchById(1) @@ -87,13 +87,13 @@ func TestGetMatchesByType(t *testing.T) { db := setupTestDb(t) match := Match{0, "qualification", "1", time.Now().UTC(), 0, 0, 0, 0, 0, 1, false, 2, false, 3, false, 4, false, - 5, false, 6, false, "", time.Now().UTC(), time.Now().UTC(), ""} + 5, false, 6, false, time.Now().UTC(), time.Now().UTC(), MatchNotPlayed} db.CreateMatch(&match) match2 := Match{0, "practice", "1", time.Now().UTC(), 0, 0, 0, 0, 0, 1, false, 2, false, 3, false, 4, false, 5, - false, 6, false, "", time.Now().UTC(), time.Now().UTC(), ""} + false, 6, false, time.Now().UTC(), time.Now().UTC(), MatchNotPlayed} db.CreateMatch(&match2) match3 := Match{0, "practice", "2", time.Now().UTC(), 0, 0, 0, 0, 0, 1, false, 2, false, 3, false, 4, false, 5, - false, 6, false, "", time.Now().UTC(), time.Now().UTC(), ""} + false, 6, false, time.Now().UTC(), time.Now().UTC(), MatchNotPlayed} db.CreateMatch(&match3) matches, err := db.GetMatchesByType("test") diff --git a/partner/tba.go b/partner/tba.go index 03969a1..6269fa3 100644 --- a/partner/tba.go +++ b/partner/tba.go @@ -319,7 +319,7 @@ func (client *TbaClient) PublishMatches(database *model.Database) error { var scoreBreakdown map[string]*TbaScoreBreakdown var redScore, blueScore *int var redCards, blueCards map[string]string - if match.Status == "complete" { + if match.IsComplete() { matchResult, err := database.GetMatchResultForMatch(match.Id) if err != nil { return err diff --git a/partner/tba_test.go b/partner/tba_test.go index 39c6934..bf677bd 100644 --- a/partner/tba_test.go +++ b/partner/tba_test.go @@ -42,7 +42,7 @@ func TestPublishMatches(t *testing.T) { database := setupTestDb(t) match1 := model.Match{Type: "qualification", DisplayName: "2", Time: time.Unix(600, 0), Red1: 7, Red2: 8, Red3: 9, - Blue1: 10, Blue2: 11, Blue3: 12, Status: "complete"} + Blue1: 10, Blue2: 11, Blue3: 12, Status: model.RedWonMatch} match2 := model.Match{Type: "elimination", DisplayName: "SF2-2", ElimRound: 2, ElimGroup: 2, ElimInstance: 2} database.CreateMatch(&match1) database.CreateMatch(&match2) diff --git a/templates/match_play.html b/templates/match_play.html index 3760c53..a9db9e5 100644 --- a/templates/match_play.html +++ b/templates/match_play.html @@ -40,7 +40,7 @@ Load - {{if eq $match.Status "complete"}} + {{if ne $match.Status ""}} Show Result diff --git a/tournament/elimination_schedule.go b/tournament/elimination_schedule.go index 35a9ec1..76cf327 100644 --- a/tournament/elimination_schedule.go +++ b/tournament/elimination_schedule.go @@ -33,7 +33,7 @@ func UpdateEliminationSchedule(database *model.Database, startTime time.Time) (b } matchIndex := 0 for _, match := range matches { - if match.Status == "complete" { + if match.IsComplete() { continue } match.Time = startTime.Add(time.Duration(matchIndex*ElimMatchSpacingSec) * time.Second) @@ -152,7 +152,7 @@ func buildEliminationMatchSet(database *model.Database, round int, group int, } var unplayedMatches []*model.Match for _, match := range matches { - if match.Status != "complete" { + if !match.IsComplete() { // Update the teams in the match if they are not yet set or are incorrect. if len(redAlliance) != 0 && !(match.Red1 == redAlliance[0].TeamId && match.Red2 == redAlliance[1].TeamId && match.Red3 == redAlliance[2].TeamId) { @@ -183,16 +183,16 @@ func buildEliminationMatchSet(database *model.Database, round int, group int, } // Check who won. - switch match.Winner { - case "R": + switch match.Status { + case model.RedWonMatch: redWins += 1 - case "B": + case model.BlueWonMatch: blueWins += 1 - case "T": + case model.TieMatch: ties = append(ties, &match) default: return []model.AllianceTeam{}, fmt.Errorf("Completed match %d has invalid winner '%s'", match.Id, - match.Winner) + match.Status) } } diff --git a/tournament/elimination_schedule_test.go b/tournament/elimination_schedule_test.go index c4dfbea..4212ba0 100644 --- a/tournament/elimination_schedule_test.go +++ b/tournament/elimination_schedule_test.go @@ -432,8 +432,8 @@ func TestEliminationSchedulePopulatePartialMatch(t *testing.T) { // Final should be updated after semifinal is concluded. CreateTestAlliances(database, 3) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "SF2-1", "B") - scoreMatch(database, "SF2-2", "B") + scoreMatch(database, "SF2-1", model.BlueWonMatch) + scoreMatch(database, "SF2-2", model.BlueWonMatch) _, err := UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, err := database.GetMatchesByType("elimination") @@ -450,8 +450,8 @@ func TestEliminationSchedulePopulatePartialMatch(t *testing.T) { // Final should be generated and populated as both semifinals conclude. CreateTestAlliances(database, 4) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "SF2-1", "R") - scoreMatch(database, "SF2-2", "R") + scoreMatch(database, "SF2-1", model.RedWonMatch) + scoreMatch(database, "SF2-2", model.RedWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, err = database.GetMatchesByType("elimination") @@ -461,8 +461,8 @@ func TestEliminationSchedulePopulatePartialMatch(t *testing.T) { assertMatch(t, matches[6], "F-2", 0, 2) assertMatch(t, matches[7], "F-3", 0, 2) } - scoreMatch(database, "SF1-1", "R") - scoreMatch(database, "SF1-2", "R") + scoreMatch(database, "SF1-1", model.RedWonMatch) + scoreMatch(database, "SF1-2", model.RedWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, err = database.GetMatchesByType("elimination") @@ -482,22 +482,22 @@ func TestEliminationScheduleCreateNextRound(t *testing.T) { CreateTestAlliances(database, 4) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "SF1-1", "B") + scoreMatch(database, "SF1-1", model.BlueWonMatch) _, err := UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, _ := database.GetMatchesByType("elimination") assert.Equal(t, 6, len(matches)) - scoreMatch(database, "SF2-1", "B") + scoreMatch(database, "SF2-1", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 6, len(matches)) - scoreMatch(database, "SF1-2", "B") + scoreMatch(database, "SF1-2", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 8, len(matches)) - scoreMatch(database, "SF2-2", "B") + scoreMatch(database, "SF2-2", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, _ = database.GetMatchesByType("elimination") @@ -514,19 +514,19 @@ func TestEliminationScheduleDetermineWinner(t *testing.T) { // Round with one tie and a sweep. CreateTestAlliances(database, 2) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-1", "T") + scoreMatch(database, "F-1", model.TieMatch) won, err := UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ := database.GetMatchesByType("elimination") assert.Equal(t, 3, len(matches)) - scoreMatch(database, "F-2", "B") + scoreMatch(database, "F-2", model.BlueWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 3, len(matches)) - scoreMatch(database, "F-3", "B") + scoreMatch(database, "F-3", model.BlueWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) if assert.Nil(t, err) { assert.True(t, won) @@ -540,30 +540,30 @@ func TestEliminationScheduleDetermineWinner(t *testing.T) { // Round with one tie and a split. CreateTestAlliances(database, 2) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-1", "R") + scoreMatch(database, "F-1", model.RedWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 3, len(matches)) - scoreMatch(database, "F-2", "T") + scoreMatch(database, "F-2", model.TieMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 3, len(matches)) - scoreMatch(database, "F-3", "B") + scoreMatch(database, "F-3", model.BlueWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 4, len(matches)) assert.Equal(t, "F-4", matches[3].DisplayName) - scoreMatch(database, "F-4", "T") + scoreMatch(database, "F-4", model.TieMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) - scoreMatch(database, "F-5", "R") + scoreMatch(database, "F-5", model.RedWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) if assert.Nil(t, err) { assert.True(t, won) @@ -575,19 +575,19 @@ func TestEliminationScheduleDetermineWinner(t *testing.T) { // Round with two ties. CreateTestAlliances(database, 2) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-1", "T") + scoreMatch(database, "F-1", model.TieMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 3, len(matches)) - scoreMatch(database, "F-2", "B") + scoreMatch(database, "F-2", model.BlueWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) matches, _ = database.GetMatchesByType("elimination") assert.Equal(t, 3, len(matches)) - scoreMatch(database, "F-3", "T") + scoreMatch(database, "F-3", model.TieMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) assert.False(t, won) @@ -595,7 +595,7 @@ func TestEliminationScheduleDetermineWinner(t *testing.T) { assert.Equal(t, 5, len(matches)) assert.Equal(t, "F-4", matches[3].DisplayName) assert.Equal(t, "F-5", matches[4].DisplayName) - scoreMatch(database, "F-4", "B") + scoreMatch(database, "F-4", model.BlueWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) if assert.Nil(t, err) { assert.True(t, won) @@ -607,17 +607,17 @@ func TestEliminationScheduleDetermineWinner(t *testing.T) { // Round with repeated ties. CreateTestAlliances(database, 2) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-1", "T") - scoreMatch(database, "F-2", "T") - scoreMatch(database, "F-3", "T") + scoreMatch(database, "F-1", model.TieMatch) + scoreMatch(database, "F-2", model.TieMatch) + scoreMatch(database, "F-3", model.TieMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-4", "T") - scoreMatch(database, "F-5", "T") - scoreMatch(database, "F-6", "T") + scoreMatch(database, "F-4", model.TieMatch) + scoreMatch(database, "F-5", model.TieMatch) + scoreMatch(database, "F-6", model.TieMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-7", "R") - scoreMatch(database, "F-8", "B") - scoreMatch(database, "F-9", "R") + scoreMatch(database, "F-7", model.RedWonMatch) + scoreMatch(database, "F-8", model.BlueWonMatch) + scoreMatch(database, "F-9", model.RedWonMatch) won, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) if assert.Nil(t, err) { assert.True(t, won) @@ -629,15 +629,15 @@ func TestEliminationScheduleRemoveUnneededMatches(t *testing.T) { CreateTestAlliances(database, 2) UpdateEliminationSchedule(database, time.Unix(0, 0)) - scoreMatch(database, "F-1", "R") - scoreMatch(database, "F-2", "R") + scoreMatch(database, "F-1", model.RedWonMatch) + scoreMatch(database, "F-2", model.RedWonMatch) _, err := UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, _ := database.GetMatchesByType("elimination") assert.Equal(t, 2, len(matches)) // Check that the deleted match is recreated if the score is changed. - scoreMatch(database, "F-2", "B") + scoreMatch(database, "F-2", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, _ = database.GetMatchesByType("elimination") @@ -652,12 +652,12 @@ func TestEliminationScheduleChangePreviousRoundResult(t *testing.T) { CreateTestAlliances(database, 4) _, err := UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) - scoreMatch(database, "SF2-1", "R") - scoreMatch(database, "SF2-2", "B") - scoreMatch(database, "SF2-3", "R") + scoreMatch(database, "SF2-1", model.RedWonMatch) + scoreMatch(database, "SF2-2", model.BlueWonMatch) + scoreMatch(database, "SF2-3", model.RedWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) - scoreMatch(database, "SF2-3", "B") + scoreMatch(database, "SF2-3", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, err := database.GetMatchesByType("elimination") @@ -668,14 +668,14 @@ func TestEliminationScheduleChangePreviousRoundResult(t *testing.T) { assertMatch(t, matches[8], "F-3", 0, 3) } - scoreMatch(database, "SF1-1", "R") - scoreMatch(database, "SF1-2", "R") + scoreMatch(database, "SF1-1", model.RedWonMatch) + scoreMatch(database, "SF1-2", model.RedWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) - scoreMatch(database, "SF1-2", "B") + scoreMatch(database, "SF1-2", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) - scoreMatch(database, "SF1-3", "B") + scoreMatch(database, "SF1-3", model.BlueWonMatch) _, err = UpdateEliminationSchedule(database, time.Unix(0, 0)) assert.Nil(t, err) matches, err = database.GetMatchesByType("elimination") @@ -714,8 +714,8 @@ func TestEliminationScheduleTiming(t *testing.T) { assert.True(t, time.Unix(3400, 0).Equal(matches[4].Time)) assert.True(t, time.Unix(4000, 0).Equal(matches[5].Time)) } - scoreMatch(database, "SF1-1", "R") - scoreMatch(database, "SF1-3", "B") + scoreMatch(database, "SF1-1", model.RedWonMatch) + scoreMatch(database, "SF1-3", model.BlueWonMatch) UpdateEliminationSchedule(database, time.Unix(5000, 0)) matches, err = database.GetMatchesByType("elimination") assert.Nil(t, err) @@ -749,8 +749,8 @@ func TestEliminationScheduleTeamPositions(t *testing.T) { match2.Blue1, match2.Blue3 = match2.Blue3, match2.Blue1 database.SaveMatch(&match1) database.SaveMatch(&match2) - scoreMatch(database, "SF1-1", "R") - scoreMatch(database, "SF2-1", "B") + scoreMatch(database, "SF1-1", model.RedWonMatch) + scoreMatch(database, "SF2-1", model.BlueWonMatch) UpdateEliminationSchedule(database, time.Unix(1000, 0)) matches, _ = database.GetMatchesByType("elimination") if assert.Equal(t, 6, len(matches)) { @@ -765,8 +765,8 @@ func TestEliminationScheduleTeamPositions(t *testing.T) { } // Advance them to the finals and verify that the team position updates have been propagated. - scoreMatch(database, "SF1-2", "R") - scoreMatch(database, "SF2-2", "B") + scoreMatch(database, "SF1-2", model.RedWonMatch) + scoreMatch(database, "SF2-2", model.BlueWonMatch) UpdateEliminationSchedule(database, time.Unix(5000, 0)) matches, _ = database.GetMatchesByType("elimination") if assert.Equal(t, 7, len(matches)) { @@ -789,9 +789,8 @@ func assertMatch(t *testing.T, match model.Match, displayName string, redAllianc assert.Equal(t, blueAlliance, match.ElimBlueAlliance) } -func scoreMatch(database *model.Database, displayName string, winner string) { +func scoreMatch(database *model.Database, displayName string, winner model.MatchStatus) { match, _ := database.GetMatchByName("elimination", displayName) - match.Status = "complete" - match.Winner = winner + match.Status = winner database.SaveMatch(match) } diff --git a/tournament/qualification_rankings.go b/tournament/qualification_rankings.go index 861e860..c5f27a9 100644 --- a/tournament/qualification_rankings.go +++ b/tournament/qualification_rankings.go @@ -20,7 +20,7 @@ func CalculateRankings(database *model.Database, preservePreviousRank bool) (gam } rankings := make(map[int]*game.Ranking) for _, match := range matches { - if match.Status != "complete" { + if !match.IsComplete() { continue } matchResult, err := database.GetMatchResultForMatch(match.Id) @@ -93,7 +93,7 @@ func CalculateTeamCards(database *model.Database, matchType string) error { return err } for _, match := range matches { - if match.Status != "complete" { + if !match.IsComplete() { continue } matchResult, err := database.GetMatchResultForMatch(match.Id) diff --git a/tournament/qualification_rankings_test.go b/tournament/qualification_rankings_test.go index 01cedab..3299585 100644 --- a/tournament/qualification_rankings_test.go +++ b/tournament/qualification_rankings_test.go @@ -85,21 +85,21 @@ func TestCalculateRankings(t *testing.T) { // Sets up a schedule and results that touches on all possible variables. func setupMatchResultsForRankings(database *model.Database) { match1 := model.Match{Type: "qualification", DisplayName: "1", Red1: 1, Red2: 2, Red3: 3, Blue1: 4, Blue2: 5, - Blue3: 6, Status: "complete"} + Blue3: 6, Status: model.RedWonMatch} database.CreateMatch(&match1) matchResult1 := model.BuildTestMatchResult(match1.Id, 1) matchResult1.RedCards = map[string]string{"2": "red"} database.CreateMatchResult(matchResult1) match2 := model.Match{Type: "qualification", DisplayName: "2", Red1: 1, Red2: 3, Red3: 5, Blue1: 2, Blue2: 4, - Blue3: 6, Status: "complete", Red2IsSurrogate: true, Blue3IsSurrogate: true} + Blue3: 6, Status: model.BlueWonMatch, Red2IsSurrogate: true, Blue3IsSurrogate: true} database.CreateMatch(&match2) matchResult2 := model.BuildTestMatchResult(match2.Id, 1) matchResult2.BlueScore = matchResult2.RedScore database.CreateMatchResult(matchResult2) match3 := model.Match{Type: "qualification", DisplayName: "3", Red1: 6, Red2: 5, Red3: 4, Blue1: 3, Blue2: 2, - Blue3: 1, Status: "complete", Red3IsSurrogate: true} + Blue3: 1, Status: model.TieMatch, Red3IsSurrogate: true} database.CreateMatch(&match3) matchResult3 := model.BuildTestMatchResult(match3.Id, 1) database.CreateMatchResult(matchResult3) @@ -109,19 +109,19 @@ func setupMatchResultsForRankings(database *model.Database) { database.CreateMatchResult(matchResult3) match4 := model.Match{Type: "practice", DisplayName: "1", Red1: 1, Red2: 2, Red3: 3, Blue1: 4, Blue2: 5, - Blue3: 6, Status: "complete"} + Blue3: 6, Status: model.RedWonMatch} database.CreateMatch(&match4) matchResult4 := model.BuildTestMatchResult(match4.Id, 1) database.CreateMatchResult(matchResult4) match5 := model.Match{Type: "elimination", DisplayName: "F-1", Red1: 1, Red2: 2, Red3: 3, Blue1: 4, Blue2: 5, - Blue3: 6, Status: "complete"} + Blue3: 6, Status: model.BlueWonMatch} database.CreateMatch(&match5) matchResult5 := model.BuildTestMatchResult(match5.Id, 1) database.CreateMatchResult(matchResult5) match6 := model.Match{Type: "qualification", DisplayName: "4", Red1: 7, Red2: 8, Red3: 9, Blue1: 10, Blue2: 11, - Blue3: 12, Status: ""} + Blue3: 12, Status: model.MatchNotPlayed} database.CreateMatch(&match6) matchResult6 := model.BuildTestMatchResult(match6.Id, 1) database.CreateMatchResult(matchResult6) diff --git a/web/api.go b/web/api.go index 13c1a67..a23d1e3 100644 --- a/web/api.go +++ b/web/api.go @@ -137,7 +137,7 @@ func (web *Web) rankingsApiHandler(w http.ResponseWriter, r *http.Request) { } highestPlayedMatch := "" for _, match := range matches { - if match.Status == "complete" { + if match.IsComplete() { highestPlayedMatch = match.DisplayName } } diff --git a/web/api_test.go b/web/api_test.go index 9e677a7..767ec79 100644 --- a/web/api_test.go +++ b/web/api_test.go @@ -64,7 +64,7 @@ func TestRankingsApi(t *testing.T) { ranking2 := RankingWithNickname{*game.TestRanking1(), "ChezyPof"} web.arena.Database.CreateRanking(&ranking1.Ranking) web.arena.Database.CreateRanking(&ranking2.Ranking) - web.arena.Database.CreateMatch(&model.Match{Type: "qualification", DisplayName: "29", Status: "complete"}) + web.arena.Database.CreateMatch(&model.Match{Type: "qualification", DisplayName: "29", Status: model.RedWonMatch}) web.arena.Database.CreateMatch(&model.Match{Type: "qualification", DisplayName: "30"}) web.arena.Database.CreateTeam(&model.Team{Id: 254, Nickname: "ChezyPof"}) web.arena.Database.CreateTeam(&model.Team{Id: 1114, Nickname: "Simbots"}) diff --git a/web/match_play.go b/web/match_play.go index cf59fb3..3794f51 100644 --- a/web/match_play.go +++ b/web/match_play.go @@ -25,7 +25,7 @@ type MatchPlayListItem struct { Id int DisplayName string Time string - Status string + Status model.MatchStatus ColorClass string } @@ -357,16 +357,15 @@ func (web *Web) commitMatchScore(match *model.Match, matchResult *model.MatchRes } // Update and save the match record to the database. - match.Status = "complete" match.ScoreCommittedAt = time.Now() redScore := matchResult.RedScoreSummary(true) blueScore := matchResult.BlueScoreSummary(true) if redScore.Score > blueScore.Score { - match.Winner = "R" + match.Status = model.RedWonMatch } else if redScore.Score < blueScore.Score { - match.Winner = "B" + match.Status = model.BlueWonMatch } else { - match.Winner = "T" + match.Status = model.TieMatch } err := web.arena.Database.SaveMatch(match) if err != nil { @@ -407,10 +406,10 @@ func (web *Web) commitMatchScore(match *model.Match, matchResult *model.MatchRes // Generate awards if the tournament is over. if isTournamentWon { var winnerAllianceId, finalistAllianceId int - if match.Winner == "R" { + if match.Status == model.RedWonMatch { winnerAllianceId = match.ElimRedAlliance finalistAllianceId = match.ElimBlueAlliance - } else if match.Winner == "B" { + } else if match.Status == model.BlueWonMatch { winnerAllianceId = match.ElimBlueAlliance finalistAllianceId = match.ElimRedAlliance } @@ -474,7 +473,7 @@ func (list MatchPlayList) Len() int { // Helper function to implement the required interface for Sort. func (list MatchPlayList) Less(i, j int) bool { - return list[i].Status != "complete" && list[j].Status == "complete" + return list[i].Status == model.MatchNotPlayed && list[j].Status != model.MatchNotPlayed } // Helper function to implement the required interface for Sort. @@ -495,12 +494,12 @@ func (web *Web) buildMatchPlayList(matchType string) (MatchPlayList, error) { matchPlayList[i].DisplayName = match.TypePrefix() + match.DisplayName matchPlayList[i].Time = match.Time.Local().Format("3:04 PM") matchPlayList[i].Status = match.Status - switch match.Winner { - case "R": + switch match.Status { + case model.RedWonMatch: matchPlayList[i].ColorClass = "danger" - case "B": + case model.BlueWonMatch: matchPlayList[i].ColorClass = "info" - case "T": + case model.TieMatch: matchPlayList[i].ColorClass = "warning" default: matchPlayList[i].ColorClass = "" diff --git a/web/match_play_test.go b/web/match_play_test.go index f608abc..f6c8db3 100644 --- a/web/match_play_test.go +++ b/web/match_play_test.go @@ -22,10 +22,10 @@ import ( func TestMatchPlay(t *testing.T) { web := setupTestWeb(t) - match1 := model.Match{Type: "practice", DisplayName: "1", Status: "complete", Winner: "R"} + match1 := model.Match{Type: "practice", DisplayName: "1", Status: model.RedWonMatch} match2 := model.Match{Type: "practice", DisplayName: "2"} - match3 := model.Match{Type: "qualification", DisplayName: "1", Status: "complete", Winner: "B"} - match4 := model.Match{Type: "elimination", DisplayName: "SF1-1", Status: "complete", Winner: "T"} + match3 := model.Match{Type: "qualification", DisplayName: "1", Status: model.BlueWonMatch} + match4 := model.Match{Type: "elimination", DisplayName: "SF1-1", Status: model.TieMatch} match5 := model.Match{Type: "elimination", DisplayName: "SF1-2"} web.arena.Database.CreateMatch(&match1) web.arena.Database.CreateMatch(&match2) @@ -52,7 +52,7 @@ func TestMatchPlayLoad(t *testing.T) { web.arena.Database.CreateTeam(&model.Team{Id: 104}) web.arena.Database.CreateTeam(&model.Team{Id: 105}) web.arena.Database.CreateTeam(&model.Team{Id: 106}) - match := model.Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 101, + match := model.Match{Type: "elimination", DisplayName: "QF4-3", Status: model.RedWonMatch, Red1: 101, Red2: 102, Red3: 103, Blue1: 104, Blue2: 105, Blue3: 106} web.arena.Database.CreateMatch(&match) recorder := web.getHttpResponse("/match_play") @@ -95,7 +95,7 @@ func TestMatchPlayShowResult(t *testing.T) { recorder := web.getHttpResponse("/match_play/1/show_result") assert.Equal(t, 500, recorder.Code) assert.Contains(t, recorder.Body.String(), "Invalid match") - match := model.Match{Type: "qualification", DisplayName: "1", Status: "complete"} + match := model.Match{Type: "qualification", DisplayName: "1", Status: model.TieMatch} web.arena.Database.CreateMatch(&match) recorder = web.getHttpResponse(fmt.Sprintf("/match_play/%d/show_result", match.Id)) assert.Equal(t, 500, recorder.Code) @@ -138,7 +138,7 @@ func TestCommitMatch(t *testing.T) { assert.Nil(t, err) assert.Equal(t, 1, matchResult.PlayNumber) match, _ = web.arena.Database.GetMatchById(1) - assert.Equal(t, "B", match.Winner) + assert.Equal(t, model.BlueWonMatch, match.Status) matchResult = model.NewMatchResult() matchResult.MatchId = match.Id @@ -147,7 +147,7 @@ func TestCommitMatch(t *testing.T) { assert.Nil(t, err) assert.Equal(t, 2, matchResult.PlayNumber) match, _ = web.arena.Database.GetMatchById(1) - assert.Equal(t, "R", match.Winner) + assert.Equal(t, model.RedWonMatch, match.Status) matchResult = model.NewMatchResult() matchResult.MatchId = match.Id @@ -155,7 +155,7 @@ func TestCommitMatch(t *testing.T) { assert.Nil(t, err) assert.Equal(t, 3, matchResult.PlayNumber) match, _ = web.arena.Database.GetMatchById(1) - assert.Equal(t, "T", match.Winner) + assert.Equal(t, model.TieMatch, match.Status) // Verify TBA publishing by checking the log for the expected failure messages. web.arena.TbaClient.BaseUrl = "fakeUrl" @@ -184,12 +184,12 @@ func TestCommitEliminationTie(t *testing.T) { err := web.commitMatchScore(match, matchResult, true) assert.Nil(t, err) match, _ = web.arena.Database.GetMatchById(1) - assert.Equal(t, "T", match.Winner) + assert.Equal(t, model.TieMatch, match.Status) match.Type = "elimination" web.arena.Database.SaveMatch(match) web.commitMatchScore(match, matchResult, true) match, _ = web.arena.Database.GetMatchById(1) - assert.Equal(t, "T", match.Winner) // No elimination tiebreakers. + assert.Equal(t, model.TieMatch, match.Status) // No elimination tiebreakers. } func TestCommitCards(t *testing.T) { diff --git a/web/match_review.go b/web/match_review.go index adcbff6..9adea7f 100644 --- a/web/match_review.go +++ b/web/match_review.go @@ -196,12 +196,12 @@ func (web *Web) buildMatchReviewList(matchType string) ([]MatchReviewListItem, e matchReviewList[i].RedScore = matchResult.RedScoreSummary(true).Score matchReviewList[i].BlueScore = matchResult.BlueScoreSummary(true).Score } - switch match.Winner { - case "R": + switch match.Status { + case model.RedWonMatch: matchReviewList[i].ColorClass = "danger" - case "B": + case model.BlueWonMatch: matchReviewList[i].ColorClass = "info" - case "T": + case model.TieMatch: matchReviewList[i].ColorClass = "warning" default: matchReviewList[i].ColorClass = "" diff --git a/web/match_review_test.go b/web/match_review_test.go index 950063d..0b17824 100644 --- a/web/match_review_test.go +++ b/web/match_review_test.go @@ -14,10 +14,10 @@ import ( func TestMatchReview(t *testing.T) { web := setupTestWeb(t) - match1 := model.Match{Type: "practice", DisplayName: "1", Status: "complete", Winner: "R"} + match1 := model.Match{Type: "practice", DisplayName: "1", Status: model.RedWonMatch} match2 := model.Match{Type: "practice", DisplayName: "2"} - match3 := model.Match{Type: "qualification", DisplayName: "1", Status: "complete", Winner: "B"} - match4 := model.Match{Type: "elimination", DisplayName: "SF1-1", Status: "complete", Winner: "T"} + match3 := model.Match{Type: "qualification", DisplayName: "1", Status: model.BlueWonMatch} + match4 := model.Match{Type: "elimination", DisplayName: "SF1-1", Status: model.TieMatch} match5 := model.Match{Type: "elimination", DisplayName: "SF1-2"} web.arena.Database.CreateMatch(&match1) web.arena.Database.CreateMatch(&match2) @@ -38,7 +38,7 @@ func TestMatchReview(t *testing.T) { func TestMatchReviewEditExistingResult(t *testing.T) { web := setupTestWeb(t) - match := model.Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 1001, + match := model.Match{Type: "elimination", DisplayName: "QF4-3", Status: model.RedWonMatch, Red1: 1001, Red2: 1002, Red3: 1003, Blue1: 1004, Blue2: 1005, Blue3: 1006, ElimRedAlliance: 1, ElimBlueAlliance: 2} web.arena.Database.CreateMatch(&match) matchResult := model.BuildTestMatchResult(match.Id, 1) @@ -78,7 +78,7 @@ func TestMatchReviewEditExistingResult(t *testing.T) { func TestMatchReviewCreateNewResult(t *testing.T) { web := setupTestWeb(t) - match := model.Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 1001, + match := model.Match{Type: "elimination", DisplayName: "QF4-3", Status: model.RedWonMatch, Red1: 1001, Red2: 1002, Red3: 1003, Blue1: 1004, Blue2: 1005, Blue3: 1006, ElimRedAlliance: 1, ElimBlueAlliance: 2} web.arena.Database.CreateMatch(&match) tournament.CreateTestAlliances(web.arena.Database, 2) diff --git a/web/queueing_display.go b/web/queueing_display.go index 71f00ec..3bbab49 100644 --- a/web/queueing_display.go +++ b/web/queueing_display.go @@ -30,7 +30,7 @@ func (web *Web) queueingDisplayHandler(w http.ResponseWriter, r *http.Request) { } var upcomingMatches []model.Match for i, match := range matches { - if match.Status == "complete" { + if match.IsComplete() { continue } upcomingMatches = append(upcomingMatches, match)