Files
sm-sitemap-plugin/classes/slots_test.go
Jakub Zych 1048c01fd9 test: unit tests for the writer, News, IndexNow, HTML groups, slugs, lastmod and slots
- XML escaping and namespaces, no priority, the image cap and file names
- News window and cap, sources and languages, the publication name
- IndexNow batches of 10 000, answer outcomes, keys and the host filter
- HTML sitemap group order, tree order and paging
- default slugs, the effective type setting, lastmod config, slot edges
2026-11-04 19:36:10 +01:00

108 lines
3.3 KiB
Go

package classes
import (
"testing"
"time"
)
// TestAssignSlots pins stable numbering without a database (D-30, RESEARCH
// Pitfall 5): appends fill the last file of their group, a left-out row
// keeps its number as a hole, only a renumber packs the listed rows again,
// and groups are numbered apart.
func TestAssignSlots(t *testing.T) {
t0 := time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)
rows := []*Slot{}
add := func(id uint64, grp string, at time.Duration) *Slot {
s := &Slot{ID: id, Grp: grp, FirstSeen: t0.Add(at), Listed: true}
rows = append(rows, s)
return s
}
files := func(grp string) []int {
var out []int
for _, r := range rows {
if r.Grp == grp && r.Listed && r.FileNo != nil {
out = append(out, *r.FileNo)
}
}
return out
}
eq := func(a []int, b ...int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
for i := uint64(1); i <= 5; i++ {
add(i, "pages", 0)
}
add(9, "posts", 0)
if !AssignSlots(rows, 2, true) || !eq(files("pages"), 1, 1, 2, 2, 3) || !eq(files("posts"), 1) {
t.Fatalf("first numbering: pages %v posts %v", files("pages"), files("posts"))
}
if AssignSlots(rows, 2, false) {
t.Fatal("a second pass changed numbers")
}
rows[1].Listed = false
if AssignSlots(rows, 2, false) || !eq(files("pages"), 1, 2, 2, 3) || *rows[1].FileNo != 1 {
t.Fatalf("after a delete: %v, hole %v", files("pages"), rows[1].FileNo)
}
add(6, "pages", time.Hour)
add(7, "pages", 2*time.Hour)
AssignSlots(rows, 2, false)
if *rows[len(rows)-2].FileNo != 3 || *rows[len(rows)-1].FileNo != 4 {
t.Fatalf("appends: %v %v", *rows[len(rows)-2].FileNo, *rows[len(rows)-1].FileNo)
}
AssignSlots(rows, 3, true)
if !eq(files("pages"), 1, 1, 1, 2, 2, 2) || rows[1].FileNo != nil {
t.Fatalf("renumber: %v, left-out row %v", files("pages"), rows[1].FileNo)
}
// A returning row fills its own hole when it still has one.
rows[1].Listed = true
n := 1
rows[1].FileNo = &n
AssignSlots(rows, 3, false)
if *rows[1].FileNo != 1 {
t.Fatalf("returning row moved to %d", *rows[1].FileNo)
}
}
// TestAssignSlotsEdges pins the edges: a size below 1 counts as 1, the
// oldest unnumbered row is appended first (first seen, then id), an empty
// table changes nothing, and a renumber with nothing listed clears every
// number.
func TestAssignSlotsEdges(t *testing.T) {
if AssignSlots(nil, 10, true) {
t.Fatal("an empty table changed")
}
t0 := time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)
rows := []*Slot{
{ID: 3, Grp: "pages", FirstSeen: t0, Listed: true},
{ID: 1, Grp: "pages", FirstSeen: t0.Add(time.Minute), Listed: true},
{ID: 2, Grp: "pages", FirstSeen: t0, Listed: true},
}
if !AssignSlots(rows, 0, false) {
t.Fatal("numbering reported no change")
}
// Size 0 is 1: one row per file, oldest first (id 2 before id 3 at the
// same time, then id 1).
if *rows[2].FileNo != 1 || *rows[0].FileNo != 2 || *rows[1].FileNo != 3 {
t.Fatalf("files: id3=%d id1=%d id2=%d", *rows[0].FileNo, *rows[1].FileNo, *rows[2].FileNo)
}
for _, r := range rows {
r.Listed = false
}
if !AssignSlots(rows, 5, true) {
t.Fatal("renumber reported no change")
}
for _, r := range rows {
if r.FileNo != nil {
t.Fatalf("row %d kept file %d after a renumber with nothing listed", r.ID, *r.FileNo)
}
}
}