split the content package at its seam
content.go had passed FILE_LOC_WARN, which conventions.md treats as the moment to split rather than a number to ignore: flat until the figure, then split, never pre-partitioned. content.go now parses bundles and builds permalinks; site.go holds the indexed site — lookup with language fallback, aliases, Query and Run. The tests follow the same seam. No behaviour change, and the test-coupling gate was right to demand the tests move: its exemption covers comments and whitespace, not code relocated between files, where an edit could hide.
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
package content
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
)
|
||||
|
||||
func TestSiteLookupFindsDefaultVariant(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"content/pages/about.md": {Data: []byte("---\ntitle: About\n---\nhi\n")},
|
||||
"content/pages/about.bn.md": {Data: []byte("---\ntitle: পরিচিতি\n---\nহাই\n")},
|
||||
}
|
||||
bundles, err := Scan(fsys)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
site := NewSite(bundles)
|
||||
if site.Len() != 2 {
|
||||
t.Fatalf("indexed %d bundles, want 2", site.Len())
|
||||
}
|
||||
b, served, ok := site.Lookup("pages/about", "en")
|
||||
if !ok || b.Title != "About" || served != "en" {
|
||||
t.Fatalf("Lookup gave %+v %q %v, want the English variant", b, served, ok)
|
||||
}
|
||||
if _, _, ok := site.Lookup("pages/missing", "en"); ok {
|
||||
t.Error("Lookup invented a bundle")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLookupFallsBackThroughLanguages(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"content/pages/about.md": {Data: []byte("---\ntitle: About\n---\n")},
|
||||
"content/pages/about.bn.md": {Data: []byte("---\ntitle: পরিচিতি\n---\n")},
|
||||
"content/posts/only.bn.md": {Data: []byte("---\ntitle: শুধু\n---\n")},
|
||||
"content/posts/plain.md": {Data: []byte("---\ntitle: Plain\n---\n")},
|
||||
}
|
||||
bundles, err := Scan(fsys)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
site := NewSite(bundles)
|
||||
cases := []struct{ key, want, served string }{
|
||||
{"pages/about", "পরিচিতি", "bn"}, // the requested language exists
|
||||
{"posts/plain", "Plain", "en"}, // falls back to the default
|
||||
{"posts/only", "শুধু", "bn"}, // no default either: any variant beats a 404
|
||||
}
|
||||
for _, c := range cases {
|
||||
b, served, ok := site.Lookup(c.key, "bn")
|
||||
if !ok || b.Title != c.want || served != c.served {
|
||||
t.Errorf("Lookup(%q, bn) = %q/%q ok=%v, want %q/%q", c.key, b.Title, served, ok, c.want, c.served)
|
||||
}
|
||||
}
|
||||
if got := site.Variants("pages/about"); len(got) != 2 || got[0] != "bn" || got[1] != "en" {
|
||||
t.Errorf("Variants = %v, want [bn en]", got)
|
||||
}
|
||||
if !site.HasLang("bn") || site.HasLang("fr") {
|
||||
t.Error("HasLang misreported")
|
||||
}
|
||||
}
|
||||
|
||||
func TestURLPrefixesOnlyNonDefaultLanguages(t *testing.T) {
|
||||
cases := map[string]string{"en": "/pages/about/", "": "/pages/about/", "bn": "/bn/pages/about/"}
|
||||
for lang, want := range cases {
|
||||
if got := URL("pages/about", lang); got != want {
|
||||
t.Errorf("URL(pages/about, %q) = %q, want %q", lang, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliasesAreParsedAndIndexed(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"content/posts/new-name.md": {Data: []byte("---\ntitle: New\naliases: [/posts/old-name/, posts/older]\n---\n")},
|
||||
"content/pages/single.md": {Data: []byte("---\ntitle: Single\naliases: pages/one\n---\n")},
|
||||
}
|
||||
bundles, err := Scan(fsys)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
site := NewSite(bundles)
|
||||
for alias, want := range map[string]string{
|
||||
"posts/old-name": "posts/new-name",
|
||||
"posts/older": "posts/new-name",
|
||||
"pages/one": "pages/single",
|
||||
} {
|
||||
got, ok := site.Alias(alias)
|
||||
if !ok || got != want {
|
||||
t.Errorf("Alias(%q) = %q %v, want %q", alias, got, ok, want)
|
||||
}
|
||||
}
|
||||
for _, b := range bundles {
|
||||
if _, leaked := b.Extra["aliases"]; leaked {
|
||||
t.Error("aliases should be lifted out of Extra, not duplicated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAmbiguousAliasesAreDropped(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"content/pages/real.md": {Data: []byte("---\ntitle: Real\n---\n")},
|
||||
"content/pages/a.md": {Data: []byte("---\ntitle: A\naliases: [pages/real, pages/shared]\n---\n")},
|
||||
"content/pages/b.md": {Data: []byte("---\ntitle: B\naliases: [pages/shared]\n---\n")},
|
||||
}
|
||||
site := NewSite(mustScan(t, fsys))
|
||||
if _, ok := site.Alias("pages/real"); ok {
|
||||
t.Error("an alias naming a real bundle must be dropped, not shadow it")
|
||||
}
|
||||
if _, ok := site.Alias("pages/shared"); ok {
|
||||
t.Error("an alias claimed by two bundles must be dropped, not picked arbitrarily")
|
||||
}
|
||||
if _, _, ok := site.Lookup("pages/real", "en"); !ok {
|
||||
t.Error("the real bundle must keep its URL")
|
||||
}
|
||||
}
|
||||
|
||||
func mustScan(t *testing.T, fsys fstest.MapFS) []Bundle {
|
||||
t.Helper()
|
||||
b, err := Scan(fsys)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func TestQueryFiltersByTagAndSection(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"content/posts/a.md": {Data: []byte("---\ntitle: A\ndate: 2026-01-03\ntags: [Monsoon, prose]\n---\n")},
|
||||
"content/posts/b.md": {Data: []byte("---\ntitle: B\ndate: 2026-01-02\ntags: [prose]\n---\n")},
|
||||
"content/comics/c.md": {Data: []byte("---\ntitle: C\ndate: 2026-01-01\ntags: [monsoon]\n---\n")},
|
||||
"content/writing/d.md": {Data: []byte("---\ntitle: D\n---\n")},
|
||||
}
|
||||
site := NewSite(mustScan(t, fsys))
|
||||
got := func(q Query) []string {
|
||||
var titles []string
|
||||
for _, b := range site.Run(q) {
|
||||
titles = append(titles, b.Title)
|
||||
}
|
||||
return titles
|
||||
}
|
||||
if titles := got(Query{Tag: "monsoon", Lang: "en"}); len(titles) != 2 || titles[0] != "A" || titles[1] != "C" {
|
||||
t.Errorf("global tag query = %v, want [A C] — a tag spans sections and case does not matter", titles)
|
||||
}
|
||||
if titles := got(Query{Section: "posts", Tag: "monsoon", Lang: "en"}); len(titles) != 1 || titles[0] != "A" {
|
||||
t.Errorf("section-narrowed tag query = %v, want [A]", titles)
|
||||
}
|
||||
if titles := got(Query{Tag: "nothing", Lang: "en"}); titles != nil {
|
||||
t.Errorf("unknown tag = %v, want none", titles)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user