package replay_test import ( _ "embed" "encoding/json" "strings" "testing" "git.sunturtle.xyz/zephyr/horse/umadump/replay" ) //go:embed Mihono_Bourbon-74.2421s-20260829.json var testRace string func TestRaceUnmarshal(t *testing.T) { // A replay is simply too large to bother converting by hand for a unit test. // Just test that we can unmarshal and certain important fields are populated. d := json.NewDecoder(strings.NewReader(testRace)) d.DisallowUnknownFields() var got replay.Race if err := d.Decode(&got); err != nil { t.Error(err) } if got.RaceType != replay.RaceTypeChampions { t.Errorf("wrong race type: want %v, got %v", replay.RaceTypeChampions, got.RaceType) } if got.RandomSeed != 1667907263 { t.Errorf("wrong random seed: want 1667907263, got %d", got.RandomSeed) } if got.RaceCourseSet.ID != 10903 { t.Errorf("wrong race course: want 10903, got %d", got.RaceCourseSet.ID) } if got.GroundCondition != replay.GroundFirm { t.Errorf("wrong ground condition: want %v, got %v", replay.GroundFirm, got.GroundCondition) } if got.Weather != replay.WeatherCloudy { t.Errorf("wrong weather: want %v, got %v", replay.WeatherCloudy, got.Weather) } if got.NumRaceHorses != 9 { t.Errorf("wrong number of race horses: want 9, got %d", got.NumRaceHorses) } if len(got.PlayerTeamMemberArray) != 3 { t.Errorf("wrong number of team members: want 3, got %d", len(got.PlayerTeamMemberArray)) } for _, m := range got.PlayerTeamMemberArray { if m.CharaID == 0 { t.Error("missing team member chara id") } if m.FinishTimeRaw == 0 { t.Error("missing team member finish time raw") } if m.RaceParam.RawSpeed == 0 { t.Error("missing team member race param raw speed") } if m.RaceParam.BaseSpeed == 0 { t.Error("missing team member race param base speed") } if m.ResponseHorseData.ViewerID == 0 { t.Error("missing team member response horse data viewer id") } if m.ResponseHorseData.TrainedCharaID == 0 { t.Error("missing team member response horse data trained chara id") } if m.ResponseHorseData.CardID == 0 { t.Error("missing team member response horse data card id") } if len(m.ResponseHorseData.SkillArray) == 0 { t.Error("missing team member response horse data skill array") } if m.ResponseHorseData.Speed == 0 { t.Error("missing team member response horse data speed") } if m.ResponseHorseData.RunningStyle == 0 { t.Error("missing team member response horse data running style") } if m.ActiveProperDistance == 0 { t.Error("missing team member active distance aptitude") } if m.ActiveProperGroundType == 0 { t.Error("missing team member active surface aptitude") } if m.TrainedCharaData.ID == 0 { t.Error("missing team member trained chara id") } if m.TrainedCharaData.CardID == 0 { t.Error("missing team member trained chara card id") } if m.TrainedCharaData.Speed == 0 { t.Error("missing team member trained chara speed") } if m.TrainedCharaData.RunningStyle == 0 { t.Error("missing team member trained chara running style") } if m.TrainedCharaData.CreateTime == "" { t.Error("missing team member trained chara create time") } if len(m.TrainedCharaData.AcquiredSkillArray) == 0 { t.Error("missing team member trained chara acquired skill array") } } if len(got.RaceHorse) != int(got.NumRaceHorses) { t.Errorf("wrong number of race horses: want %d, got %d", got.NumRaceHorses, len(got.RaceHorse)) } zeroFinish, zeroDelta := 0, 0 for _, m := range got.RaceHorse { if m.CharaID == 0 { t.Error("missing race horse chara id") } if m.FinishOrder == 0 { zeroFinish++ } if m.FinishTimeRaw == 0 { t.Error("missing race horse finish time raw") } if m.FinishDiffTimeFromPrev == 0 { zeroDelta++ } if m.RaceParam.RawSpeed == 0 { t.Error("missing race horse race param raw speed") } if m.RaceParam.BaseSpeed == 0 { t.Error("missing race horse race param base speed") } if m.ResponseHorseData.ViewerID == 0 { t.Error("missing race horse response horse data viewer id") } if m.ResponseHorseData.TrainedCharaID == 0 { t.Error("missing race horse response horse data trained chara id") } if m.ResponseHorseData.CardID == 0 { t.Error("missing race horse response horse data card id") } if len(m.ResponseHorseData.SkillArray) == 0 { t.Error("missing race horse response horse data skill array") } if m.ResponseHorseData.Speed == 0 { t.Error("missing race horse response horse data speed") } if m.ResponseHorseData.RunningStyle == 0 { t.Error("missing race horse response horse data running style") } if m.ActiveProperDistance == 0 { t.Error("missing race horse active distance aptitude") } if m.ActiveProperGroundType == 0 { t.Error("missing race horse active surface aptitude") } if m.TrainedCharaData.ID == 0 { t.Error("missing race horse trained chara id") } if m.TrainedCharaData.CardID == 0 { t.Error("missing race horse trained chara card id") } if m.TrainedCharaData.Speed == 0 { t.Error("missing race horse trained chara speed") } if m.TrainedCharaData.RunningStyle == 0 { t.Error("missing race horse trained chara running style") } if m.TrainedCharaData.CreateTime == "" { t.Error("missing race horse trained chara create time") } if len(m.TrainedCharaData.AcquiredSkillArray) == 0 { t.Error("missing race horse trained chara acquired skill array") } } if zeroFinish != 1 { t.Errorf("%d horses in index 0 finish", zeroFinish) } if zeroDelta != 1 { t.Errorf("%d horses with zero finish time delta", zeroDelta) } if got.SimDataBase64 != encodedSimdata { t.Errorf("wrong simdata:\nwant %s\n got %s", encodedSimdata, got.SimDataBase64) } if len(got.HorseIndexByFinishOrder) != len(got.RaceHorse) { t.Errorf("length of horseIndexByFinishOrder (%d) doesn't match length of raceHorse (%d)", len(got.HorseIndexByFinishOrder), len(got.RaceHorse)) } if len(got.HorseIndexByPopularity) != len(got.RaceHorse) { t.Errorf("length of horseIndexByPopularity (%d) doesn't match length of raceHorse (%d)", len(got.HorseIndexByPopularity), len(got.RaceHorse)) } }