From e01dc31e6da71584bde1efe7b35e7175d2948ebe Mon Sep 17 00:00:00 2001 From: Patrick Fairbank Date: Sun, 7 Aug 2016 20:18:53 -0700 Subject: [PATCH] Update match review interface for 2016. --- match_review.go | 5 +- match_review_test.go | 142 +++++++++++++++---------------- static/js/match_review.js | 83 +++++++++--------- templates/edit_match_result.html | 128 +++++++++++++++++++++------- 4 files changed, 209 insertions(+), 149 deletions(-) diff --git a/match_review.go b/match_review.go index a7b18ad..06d7c45 100644 --- a/match_review.go +++ b/match_review.go @@ -116,8 +116,9 @@ func MatchReviewEditPostHandler(w http.ResponseWriter, r *http.Request) { r.ParseForm() matchResultJson := MatchResultDb{Id: matchResult.Id, MatchId: match.Id, PlayNumber: matchResult.PlayNumber, - RedScoreJson: r.PostFormValue("redScoreJson"), BlueScoreJson: r.PostFormValue("blueScoreJson"), - RedCardsJson: r.PostFormValue("redCardsJson"), BlueCardsJson: r.PostFormValue("blueCardsJson")} + MatchType: matchResult.MatchType, RedScoreJson: r.PostFormValue("redScoreJson"), + BlueScoreJson: r.PostFormValue("blueScoreJson"), RedCardsJson: r.PostFormValue("redCardsJson"), + BlueCardsJson: r.PostFormValue("blueCardsJson")} // Deserialize the JSON using the same mechanism as to store scoring information in the database. matchResult, err = matchResultJson.deserialize() diff --git a/match_review_test.go b/match_review_test.go index 992d101..c07802f 100644 --- a/match_review_test.go +++ b/match_review_test.go @@ -4,6 +4,7 @@ package main import ( + "fmt" "github.com/stretchr/testify/assert" "testing" ) @@ -39,91 +40,86 @@ func TestMatchReview(t *testing.T) { } func TestMatchReviewEditExistingResult(t *testing.T) { - // TODO(patrick): Update test for 2016. - /* - clearDb() - defer clearDb() - var err error - db, err = OpenDatabase(testDbPath) - assert.Nil(t, err) - defer db.Close() - eventSettings, _ = db.GetEventSettings() - mainArena.Setup() + clearDb() + defer clearDb() + var err error + db, err = OpenDatabase(testDbPath) + assert.Nil(t, err) + defer db.Close() + eventSettings, _ = db.GetEventSettings() + mainArena.Setup() - match := Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 1001, - Red2: 1002, Red3: 1003, Blue1: 1004, Blue2: 1005, Blue3: 1006} - db.CreateMatch(&match) - matchResult := buildTestMatchResult(match.Id, 1) - db.CreateMatchResult(&matchResult) - createTestAlliances(db, 2) + match := Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 1001, + Red2: 1002, Red3: 1003, Blue1: 1004, Blue2: 1005, Blue3: 1006} + db.CreateMatch(&match) + matchResult := buildTestMatchResult(match.Id, 1) + matchResult.MatchType = match.Type + db.CreateMatchResult(&matchResult) + createTestAlliances(db, 2) - recorder := getHttpResponse("/match_review") - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "QF4-3") - assert.Contains(t, recorder.Body.String(), "92") // The red score - assert.Contains(t, recorder.Body.String(), "104") // The blue score + recorder := getHttpResponse("/match_review") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "QF4-3") + assert.Contains(t, recorder.Body.String(), "176") // The red score + assert.Contains(t, recorder.Body.String(), "113") // The blue score - // Check response for non-existent match. - recorder = getHttpResponse(fmt.Sprintf("/match_review/%d/edit", 12345)) - assert.Equal(t, 500, recorder.Code) - assert.Contains(t, recorder.Body.String(), "No such match") + // Check response for non-existent match. + recorder = getHttpResponse(fmt.Sprintf("/match_review/%d/edit", 12345)) + assert.Equal(t, 500, recorder.Code) + assert.Contains(t, recorder.Body.String(), "No such match") - recorder = getHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id)) - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "QF4-3") + recorder = getHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id)) + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "QF4-3") - // Update the score to something else. - postBody := "redScoreJson={\"AutoRobotSet\":true}&blueScoreJson={\"Stacks\":[{\"Totes\":6,\"Container\":true,\"Litter\":true}]," + - "\"Fouls\":[{\"TeamId\":973,\"Rule\":\"G22\"}]}&redCardsJson={\"105\":\"yellow\"}&blueCardsJson={}" - recorder = postHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id), postBody) - assert.Equal(t, 302, recorder.Code) + // Update the score to something else. + postBody := "redScoreJson={\"AutoLowGoals\":5}&blueScoreJson={\"DefensesCrossed\":[2,2,1,2,2]," + + "\"Fouls\":[{\"TeamId\":973,\"Rule\":\"G22\"}]}&redCardsJson={\"105\":\"yellow\"}&blueCardsJson={}" + recorder = postHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id), postBody) + assert.Equal(t, 302, recorder.Code) - // Check for the updated scores back on the match list page. - recorder = getHttpResponse("/match_review") - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "QF4-3") - assert.Contains(t, recorder.Body.String(), "4") // The red score - assert.Contains(t, recorder.Body.String(), "36") // The blue score - */ + // Check for the updated scores back on the match list page. + recorder = getHttpResponse("/match_review") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "QF4-3") + assert.Contains(t, recorder.Body.String(), "30") // The red score + assert.Contains(t, recorder.Body.String(), "65") // The blue score } func TestMatchReviewCreateNewResult(t *testing.T) { - // TODO(patrick): Update test for 2016. - /* - clearDb() - defer clearDb() - var err error - db, err = OpenDatabase(testDbPath) - assert.Nil(t, err) - defer db.Close() - eventSettings, _ = db.GetEventSettings() + clearDb() + defer clearDb() + var err error + db, err = OpenDatabase(testDbPath) + assert.Nil(t, err) + defer db.Close() + eventSettings, _ = db.GetEventSettings() - match := Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 1001, - Red2: 1002, Red3: 1003, Blue1: 1004, Blue2: 1005, Blue3: 1006} - db.CreateMatch(&match) - createTestAlliances(db, 2) + match := Match{Type: "elimination", DisplayName: "QF4-3", Status: "complete", Winner: "R", Red1: 1001, + Red2: 1002, Red3: 1003, Blue1: 1004, Blue2: 1005, Blue3: 1006} + db.CreateMatch(&match) + createTestAlliances(db, 2) - recorder := getHttpResponse("/match_review") - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "QF4-3") - assert.NotContains(t, recorder.Body.String(), "92") // The red score - assert.NotContains(t, recorder.Body.String(), "104") // The blue score + recorder := getHttpResponse("/match_review") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "QF4-3") + assert.NotContains(t, recorder.Body.String(), "176") // The red score + assert.NotContains(t, recorder.Body.String(), "113") // The blue score - recorder = getHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id)) - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "QF4-3") + recorder = getHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id)) + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "QF4-3") - // Update the score to something else. - postBody := "redScoreJson={\"AutoToteSet\":true}&blueScoreJson={\"Stacks\":[{\"Totes\":6,\"Container\":true,\"Litter\":true}]," + - "\"Fouls\":[{\"TeamId\":973,\"Rule\":\"G22\"}]}&redCardsJson={\"105\":\"yellow\"}&blueCardsJson={}" - recorder = postHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id), postBody) - assert.Equal(t, 302, recorder.Code) + // Update the score to something else. + postBody := "redScoreJson={\"AutoDefensesReached\":3}&blueScoreJson={\"HighGoals\":3," + + "\"Fouls\":[{\"TeamId\":973,\"Rule\":\"G22\"}]}&redCardsJson={\"105\":\"yellow\"}&blueCardsJson={}" + recorder = postHttpResponse(fmt.Sprintf("/match_review/%d/edit", match.Id), postBody) + assert.Equal(t, 302, recorder.Code) - // Check for the updated scores back on the match list page. - recorder = getHttpResponse("/match_review") - assert.Equal(t, 200, recorder.Code) - assert.Contains(t, recorder.Body.String(), "QF4-3") - assert.Contains(t, recorder.Body.String(), "6") // The red score - assert.Contains(t, recorder.Body.String(), "36") // The blue score - */ + // Check for the updated scores back on the match list page. + recorder = getHttpResponse("/match_review") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "QF4-3") + assert.Contains(t, recorder.Body.String(), "11") // The red score + assert.Contains(t, recorder.Body.String(), "15") // The blue score } diff --git a/static/js/match_review.js b/static/js/match_review.js index 487c8a3..e673667 100644 --- a/static/js/match_review.js +++ b/static/js/match_review.js @@ -32,26 +32,30 @@ var renderResults = function(alliance) { $("#" + alliance + "Score").html(scoreContent); // Set the values of the form fields from the JSON results data. - $("input[name=" + alliance + "AutoRobotSet]").prop("checked", result.score.AutoRobotSet); - $("input[name=" + alliance + "AutoContainerSet]").prop("checked", result.score.AutoContainerSet); - $("input[name=" + alliance + "AutoToteSet]").prop("checked", result.score.AutoToteSet); - $("input[name=" + alliance + "AutoStackedToteSet]").prop("checked", result.score.AutoStackedToteSet); - $("input[name=" + alliance + "CoopertitionSet]").prop("checked", result.score.CoopertitionSet); - $("input[name=" + alliance + "CoopertitionStack]").prop("checked", result.score.CoopertitionStack); + $("input[name=" + alliance + "AutoDefense1Crossings]").val(result.score.AutoDefensesCrossed[0]); + $("input[name=" + alliance + "AutoDefense2Crossings]").val(result.score.AutoDefensesCrossed[1]); + $("input[name=" + alliance + "AutoDefense3Crossings]").val(result.score.AutoDefensesCrossed[2]); + $("input[name=" + alliance + "AutoDefense4Crossings]").val(result.score.AutoDefensesCrossed[3]); + $("input[name=" + alliance + "AutoDefense5Crossings]").val(result.score.AutoDefensesCrossed[4]); + $("input[name=" + alliance + "AutoDefensesReached]").val(result.score.AutoDefensesReached); + $("input[name=" + alliance + "AutoHighGoals]").val(result.score.AutoHighGoals); + $("input[name=" + alliance + "AutoLowGoals]").val(result.score.AutoLowGoals); - if (result.score.Stacks != null) { - $.each(result.score.Stacks, function(k, v) { - $("#" + alliance + "Stack" + k + "Title").text("Stack " + (k + 1)); - $("input[name=" + alliance + "Stack" + k + "Totes]").val(v.Totes); - $("input[name=" + alliance + "Stack" + k + "Container]").prop("checked", v.Container); - $("input[name=" + alliance + "Stack" + k + "Litter]").prop("checked", v.Litter); - }); - } + $("input[name=" + alliance + "Defense1Crossings]").val(result.score.DefensesCrossed[0]); + $("input[name=" + alliance + "Defense2Crossings]").val(result.score.DefensesCrossed[1]); + $("input[name=" + alliance + "Defense3Crossings]").val(result.score.DefensesCrossed[2]); + $("input[name=" + alliance + "Defense4Crossings]").val(result.score.DefensesCrossed[3]); + $("input[name=" + alliance + "Defense5Crossings]").val(result.score.DefensesCrossed[4]); + $("input[name=" + alliance + "HighGoals]").val(result.score.HighGoals); + $("input[name=" + alliance + "LowGoals]").val(result.score.LowGoals); + $("input[name=" + alliance + "Challenges]").val(result.score.Challenges); + $("input[name=" + alliance + "Scales]").val(result.score.Scales); if (result.score.Fouls != null) { $.each(result.score.Fouls, function(k, v) { $("input[name=" + alliance + "Foul" + k + "Team][value=" + v.TeamId + "]").prop("checked", true); $("input[name=" + alliance + "Foul" + k + "Rule]").val(v.Rule); + $("input[name=" + alliance + "Foul" + k + "IsTechnical]").prop("checked", v.IsTechnical); $("input[name=" + alliance + "Foul" + k + "Time]").val(v.TimeInMatchSec); }); } @@ -71,26 +75,31 @@ var updateResults = function(alliance) { formData[v.name] = v.value; }); - result.score.AutoRobotSet = formData[alliance + "AutoRobotSet"] == "on"; - result.score.AutoContainerSet = formData[alliance + "AutoContainerSet"] == "on"; - result.score.AutoToteSet = formData[alliance + "AutoToteSet"] == "on"; - result.score.AutoStackedToteSet = formData[alliance + "AutoStackedToteSet"] == "on"; - result.score.CoopertitionSet = formData[alliance + "CoopertitionSet"] == "on"; - result.score.CoopertitionStack = formData[alliance + "CoopertitionStack"] == "on"; - - result.score.Stacks = []; - for (var i = 0; formData[alliance + "Stack" + i + "Totes"]; i++) { - var prefix = alliance + "Stack" + i; - var stack = {Totes: parseInt(formData[prefix + "Totes"]), - Container: formData[prefix + "Container"] == "on", - Litter: formData[prefix + "Litter"] == "on"} - result.score.Stacks.push(stack); - } + result.score.AutoDefensesCrossed = []; + result.score.AutoDefensesCrossed.push(parseInt(formData[alliance + "AutoDefense1Crossings"])); + result.score.AutoDefensesCrossed.push(parseInt(formData[alliance + "AutoDefense2Crossings"])); + result.score.AutoDefensesCrossed.push(parseInt(formData[alliance + "AutoDefense3Crossings"])); + result.score.AutoDefensesCrossed.push(parseInt(formData[alliance + "AutoDefense4Crossings"])); + result.score.AutoDefensesCrossed.push(parseInt(formData[alliance + "AutoDefense5Crossings"])); + result.score.AutoDefensesReached = parseInt(formData[alliance + "AutoDefensesReached"]); + result.score.AutoHighGoals = parseInt(formData[alliance + "AutoHighGoals"]); + result.score.AutoLowGoals = parseInt(formData[alliance + "AutoLowGoals"]); + result.score.DefensesCrossed = []; + result.score.DefensesCrossed.push(parseInt(formData[alliance + "Defense1Crossings"])); + result.score.DefensesCrossed.push(parseInt(formData[alliance + "Defense2Crossings"])); + result.score.DefensesCrossed.push(parseInt(formData[alliance + "Defense3Crossings"])); + result.score.DefensesCrossed.push(parseInt(formData[alliance + "Defense4Crossings"])); + result.score.DefensesCrossed.push(parseInt(formData[alliance + "Defense5Crossings"])); + result.score.HighGoals = parseInt(formData[alliance + "HighGoals"]); + result.score.LowGoals = parseInt(formData[alliance + "LowGoals"]); + result.score.Challenges = parseInt(formData[alliance + "Challenges"]); + result.score.Scales = parseInt(formData[alliance + "Scales"]); result.score.Fouls = []; for (var i = 0; formData[alliance + "Foul" + i + "Time"]; i++) { var prefix = alliance + "Foul" + i; var foul = {TeamId: parseInt(formData[prefix + "Team"]), Rule: formData[prefix + "Rule"], + IsTechnical: formData[prefix + "IsTechnical"] == "on", TimeInMatchSec: parseFloat(formData[prefix + "Time"])}; result.score.Fouls.push(foul); } @@ -101,22 +110,6 @@ var updateResults = function(alliance) { }); } -// Appends a blank stack to the end of the list. -var addStack = function(alliance) { - updateResults(alliance); - var result = allianceResults[alliance]; - result.score.Stacks.push({Totes: 0, Container: false, Litter: false}) - renderResults(alliance); -} - -// Removes the given stack from the list. -var deleteStack = function(alliance, index) { - updateResults(alliance); - var result = allianceResults[alliance]; - result.score.Stacks.splice(index, 1); - renderResults(alliance); -} - // Appends a blank foul to the end of the list. var addFoul = function(alliance) { updateResults(alliance); diff --git a/templates/edit_match_result.html b/templates/edit_match_result.html index 218d059..aec6d57 100644 --- a/templates/edit_match_result.html +++ b/templates/edit_match_result.html @@ -27,40 +27,104 @@
Autonomous
- -
- -
- -
- -
+
+ Defense Crossings
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
Teleoperated
- -
- -
-
- {{"{{#each score.Stacks}}"}} -
- Stack - -
-
- -
- -
- -
+
+ Defense Crossings
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
- {{"{{/each}}"}} - +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+


Fouls {{"{{#each score.Fouls}}"}} @@ -96,6 +160,12 @@
+
+ +
+ +
+