M0: skelett, byggkedja och dokumentation för JP Subway Pussel
- Go 1.27 + Ebitengine v2.10, intern upplösning 320x180 med heltalsskalning - internal/res (resursuppslag), internal/rng (seedad slump), internal/level (banformat, validering, BFS-lösbarhet) med tester; internal/archtest kontrollerar att bara presentationslagret beror på Ebitengine - tools/build: debug -> build/debug/, release -> build/release/<os>-<arch>/ med resources/ bredvid binären; Windows korsbyggs utan C-verktyg - VS Code tasks (build/test/release) och launch (dlv) - Första banan 001-flygplatsen, sv/en-texter, skyltordbok, placeholder-sprite - doc/: spelbeskrivning (renskriven), mål och tester, roadmap med teknikval (M0–M12), plan.md; README med bygg- och beroendeinformation Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
58
internal/archtest/arch_test.go
Normal file
58
internal/archtest/arch_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
// Package archtest innehåller arkitekturtester: regler om vilka paket som
|
||||
// får bero på vad. Körs som vanliga tester med `go test ./...`.
|
||||
package archtest
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Paket (relativt modulroten) som får importera Ebitengine. All annan kod
|
||||
// under internal/ ska gå att testa utan fönster.
|
||||
var mayUseEbitengine = map[string]bool{
|
||||
"internal/game": true,
|
||||
"internal/ui": true,
|
||||
"internal/audio": true,
|
||||
}
|
||||
|
||||
const ebitengine = "github.com/hajimehoshi/ebiten/"
|
||||
|
||||
func TestOnlyPresentationPackagesImportEbitengine(t *testing.T) {
|
||||
root := goList(t, "-m", "-f", "{{.Dir}}")
|
||||
module := goList(t, "-m", "-f", "{{.Path}}")
|
||||
|
||||
out := goListIn(t, root, "-f", "{{.ImportPath}}|{{join .Deps \",\"}}", "./...")
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
pkg, deps, ok := strings.Cut(line, "|")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rel := strings.TrimPrefix(strings.TrimPrefix(pkg, module), "/")
|
||||
if strings.HasPrefix(rel, "cmd/") || mayUseEbitengine[rel] {
|
||||
continue
|
||||
}
|
||||
for _, d := range strings.Split(deps, ",") {
|
||||
if strings.HasPrefix(d, ebitengine) {
|
||||
t.Errorf("%s får inte bero på Ebitengine (via %s) – flytta logiken till ett rent paket eller lägg till paketet i mayUseEbitengine", rel, d)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func goList(t *testing.T, args ...string) string {
|
||||
t.Helper()
|
||||
return goListIn(t, "", args...)
|
||||
}
|
||||
|
||||
func goListIn(t *testing.T, dir string, args ...string) string {
|
||||
t.Helper()
|
||||
cmd := exec.Command("go", append([]string{"list"}, args...)...)
|
||||
cmd.Dir = dir
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatalf("go list %v: %v", args, err)
|
||||
}
|
||||
return strings.TrimSpace(string(out))
|
||||
}
|
||||
Reference in New Issue
Block a user