diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-21 10:29:21 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-21 10:29:21 +0900 |
| commit | e8db174d3e464a5764a9f4bfd82172261bd50519 (patch) | |
| tree | 68cb8f0713fcc1f960a650d879232cb4c20ca6cd /backend/tournament/service_test.go | |
| parent | 1be106ac53caa019a8912af932a43570fa8c052d (diff) | |
| download | phperkaigi-2026-albatross-e8db174d3e464a5764a9f4bfd82172261bd50519.tar.gz phperkaigi-2026-albatross-e8db174d3e464a5764a9f4bfd82172261bd50519.tar.zst phperkaigi-2026-albatross-e8db174d3e464a5764a9f4bfd82172261bd50519.zip | |
refactor(api): separate business logic into game, tournament, session packages
Extract business logic from api/handler.go into dedicated service packages:
- session: context helpers (resolves admin → api import dependency)
- game: game state, code submission, ranking, watch logic
- tournament: bracket construction and seed ordering
- api/convert.go: domain → API type conversion functions
api/handler.go is now a thin adapter that delegates to services and
maps domain errors to HTTP status codes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'backend/tournament/service_test.go')
| -rw-r--r-- | backend/tournament/service_test.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/backend/tournament/service_test.go b/backend/tournament/service_test.go new file mode 100644 index 0000000..d1ca78c --- /dev/null +++ b/backend/tournament/service_test.go @@ -0,0 +1,97 @@ +package tournament + +import "testing" + +func TestStandardBracketSeeds(t *testing.T) { + tests := []struct { + name string + bracketSize int + expected []int + }{ + { + name: "bracket_size=2", + bracketSize: 2, + expected: []int{1, 2}, + }, + { + name: "bracket_size=4", + bracketSize: 4, + expected: []int{1, 4, 2, 3}, + }, + { + name: "bracket_size=8", + bracketSize: 8, + expected: []int{1, 8, 4, 5, 2, 7, 3, 6}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := StandardBracketSeeds(tt.bracketSize) + if len(got) != len(tt.expected) { + t.Fatalf("expected length %d, got %d", len(tt.expected), len(got)) + } + for i, v := range tt.expected { + if got[i] != v { + t.Errorf("position %d: expected seed %d, got %d", i, v, got[i]) + } + } + }) + } +} + +func TestStandardBracketSeeds_Seed1And2OppositeSides(t *testing.T) { + seeds := StandardBracketSeeds(8) + seed1Pos := -1 + seed2Pos := -1 + for i, s := range seeds { + if s == 1 { + seed1Pos = i + } + if s == 2 { + seed2Pos = i + } + } + if seed1Pos >= 4 { + t.Errorf("Seed 1 should be in first half, but at position %d", seed1Pos) + } + if seed2Pos < 4 { + t.Errorf("Seed 2 should be in second half, but at position %d", seed2Pos) + } +} + +func TestStandardBracketSeeds_AllSeedsPresent(t *testing.T) { + for _, size := range []int{2, 4, 8, 16} { + seeds := StandardBracketSeeds(size) + seen := make(map[int]bool) + for _, s := range seeds { + if s < 1 || s > size { + t.Errorf("bracket_size=%d: seed %d out of range", size, s) + } + if seen[s] { + t.Errorf("bracket_size=%d: duplicate seed %d", size, s) + } + seen[s] = true + } + if len(seen) != size { + t.Errorf("bracket_size=%d: expected %d unique seeds, got %d", size, size, len(seen)) + } + } +} + +func TestFindSeedByUserID(t *testing.T) { + entries := []TournamentEntry{ + {User: Player{UserID: 10}, Seed: 1}, + {User: Player{UserID: 20}, Seed: 2}, + {User: Player{UserID: 30}, Seed: 3}, + } + + if got := findSeedByUserID(entries, 10); got != 1 { + t.Errorf("expected seed 1 for user 10, got %d", got) + } + if got := findSeedByUserID(entries, 20); got != 2 { + t.Errorf("expected seed 2 for user 20, got %d", got) + } + if got := findSeedByUserID(entries, 999); got != 0 { + t.Errorf("expected seed 0 for unknown user, got %d", got) + } +} |
