aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/game/hub_test.go
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-28 17:00:35 +0900
committernsfisis <nsfisis@gmail.com>2026-02-28 17:00:35 +0900
commitb15f06ece6a9dac01a06688be39e437cfa8ed257 (patch)
tree2a713f2079d7055f5777c84db29f9c25bf867e33 /backend/game/hub_test.go
parent10f0cd9dbc408b171fbd6a96ed1b552407046b13 (diff)
downloadphperkaigi-2026-albatross-b15f06ece6a9dac01a06688be39e437cfa8ed257.tar.gz
phperkaigi-2026-albatross-b15f06ece6a9dac01a06688be39e437cfa8ed257.tar.zst
phperkaigi-2026-albatross-b15f06ece6a9dac01a06688be39e437cfa8ed257.zip
fix(game): normalize CRLF to LF in stdin and code before execution
DB stores stdin/code with CRLF intact, but workers expect LF. Add normalizeCRLF helper and apply it to code and stdin in EnqueueTestTasks. Refactor normalizeTestcaseResultOutput to reuse the same helper.
Diffstat (limited to 'backend/game/hub_test.go')
-rw-r--r--backend/game/hub_test.go53
1 files changed, 53 insertions, 0 deletions
diff --git a/backend/game/hub_test.go b/backend/game/hub_test.go
index 5aa440b..1d493b9 100644
--- a/backend/game/hub_test.go
+++ b/backend/game/hub_test.go
@@ -249,6 +249,59 @@ func TestNormalizeTestcaseResultOutput(t *testing.T) {
}
}
+func TestNormalizeCRLF(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ want string
+ }{
+ {"CRLF to LF", "hello\r\nworld", "hello\nworld"},
+ {"CR to LF", "hello\rworld", "hello\nworld"},
+ {"LF unchanged", "hello\nworld", "hello\nworld"},
+ {"lone CRLF", "\r\n", "\n"},
+ {"empty string", "", ""},
+ {"multiple CRLF", "a\r\nb\r\nc", "a\nb\nc"},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := normalizeCRLF(tt.input)
+ if got != tt.want {
+ t.Errorf("normalizeCRLF(%q) = %q, want %q", tt.input, got, tt.want)
+ }
+ })
+ }
+}
+
+func TestEnqueueTestTasks_NormalizesCRLF(t *testing.T) {
+ testcases := []db.Testcase{
+ {TestcaseID: 1, ProblemID: 10, Stdin: "input\r\n", Stdout: "output"},
+ }
+
+ tq := &mockTaskQueue{}
+ mq := &mockQuerier{
+ listTestcasesByGameIDFunc: func(_ context.Context, _ int32) ([]db.Testcase, error) {
+ return testcases, nil
+ },
+ }
+
+ hub := &Hub{q: mq, taskQueue: tq, ctx: context.Background()}
+
+ err := hub.EnqueueTestTasks(context.Background(), 100, 1, 42, "php", "<?php\r\necho 1;")
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+
+ if len(tq.enqueued) != 1 {
+ t.Fatalf("expected 1 enqueued task, got %d", len(tq.enqueued))
+ }
+ if tq.enqueued[0].Stdin != "input\n" {
+ t.Errorf("expected stdin CRLF normalized, got %q", tq.enqueued[0].Stdin)
+ }
+ if tq.enqueued[0].Code != "<?php\necho 1;" {
+ t.Errorf("expected code CRLF normalized, got %q", tq.enqueued[0].Code)
+ }
+}
+
func TestCalcCodeSize_PHP(t *testing.T) {
hub := &Hub{}
tests := []struct {