package towel import ( "context" "os" "strings" "testing" ) func TestContextAccessorsRoundTrip(t *testing.T) { ctx := context.Background() ctx = WithActor(ctx, "user-1") ctx = WithOrganization(ctx, "org-9") ctx = WithCollection(ctx, "col-3") ctx = WithLocale(ctx, "pl") if got, ok := Actor(ctx); !ok || got != "user-1" { t.Fatalf("Actor = (%q, %v)", got, ok) } if got, ok := Organization(ctx); !ok || got != "org-9" { t.Fatalf("Organization = (%q, %v)", got, ok) } if got, ok := Collection(ctx); !ok || got != "col-3" { t.Fatalf("Collection = (%q, %v)", got, ok) } if got, ok := Locale(ctx); !ok || got != "pl" { t.Fatalf("Locale = (%q, %v)", got, ok) } other := context.Background() if _, ok := Actor(other); ok { t.Fatal("Actor leaked across contexts") } } func TestNoPackageGlobalRequestState(t *testing.T) { entries, err := os.ReadDir(".") if err != nil { t.Fatal(err) } for _, entry := range entries { name := entry.Name() if entry.IsDir() || !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") { continue } src, err := os.ReadFile(name) if err != nil { t.Fatal(err) } // Reject package-level request-state variables. Type keys are ok. for _, line := range strings.Split(string(src), "\n") { trim := strings.TrimSpace(line) if strings.HasPrefix(trim, "var ") && !strings.Contains(trim, "struct{}") && !strings.Contains(trim, "key") { if strings.Contains(strings.ToLower(trim), "actor") || strings.Contains(strings.ToLower(trim), "locale") || strings.Contains(strings.ToLower(trim), "organization") || strings.Contains(strings.ToLower(trim), "collection") { t.Fatalf("package-global request state in %s: %s", name, trim) } } } } }