package showcase
import (
"strings"
"testing"
)
// makeTestSummaries builds a small slice of ProjectSummary with rank history
// suitable for unit-testing the SVG generator without touching the filesystem.
func makeTestSummaries() []ProjectSummary {
return []ProjectSummary{
{
Name: "alpha",
RankHistory: []RepoRankHistory{
{Spot: 1, Anchor: "now", SnapshotDate: "2026-05-27"},
{Spot: 2, Anchor: "1w", SnapshotDate: "2026-05-20"},
{Spot: 2, Anchor: "2w", SnapshotDate: "2026-05-13"},
{Spot: 3, Anchor: "3w", SnapshotDate: "2026-05-06"},
{Spot: 0, Anchor: "4w"}, // missing snapshot week
},
},
{
Name: "beta",
RankHistory: []RepoRankHistory{
{Spot: 2, Anchor: "now", SnapshotDate: "2026-05-27"},
{Spot: 1, Anchor: "1w", SnapshotDate: "2026-05-20"},
{Spot: 1, Anchor: "2w", SnapshotDate: "2026-05-13"},
{Spot: 0, Anchor: "3w"},
{Spot: 0, Anchor: "4w"},
},
},
{
// Project with no rank data at all should be skipped.
Name: "ghost",
RankHistory: []RepoRankHistory{{Spot: 0}, {Spot: 0}, {Spot: 0}, {Spot: 0}, {Spot: 0}},
},
}
}
func TestGenerateRankHistorySVG_IsValidSVG(t *testing.T) {
t.Parallel()
svg := GenerateRankHistorySVG(makeTestSummaries())
if !strings.HasPrefix(svg, "', got suffix: %.40s", svg[len(svg)-40:])
}
}
func TestGenerateRankHistorySVG_ContainsProjectNames(t *testing.T) {
t.Parallel()
svg := GenerateRankHistorySVG(makeTestSummaries())
if !strings.Contains(svg, `"name":"alpha"`) {
t.Error("SVG JSON data missing project 'alpha'")
}
if !strings.Contains(svg, `"name":"beta"`) {
t.Error("SVG JSON data missing project 'beta'")
}
// 'ghost' has no valid data points and must be excluded.
if strings.Contains(svg, `"name":"ghost"`) {
t.Error("SVG JSON data should not contain 'ghost' (no rank data)")
}
}
func TestGenerateRankHistorySVG_ContainsInteractiveJS(t *testing.T) {
t.Parallel()
svg := GenerateRankHistorySVG(makeTestSummaries())
// Key JS functions must be present for interactivity.
for _, fn := range []string{"onEnter", "onLeave", "moveTT"} {
if !strings.Contains(svg, fn) {
t.Errorf("SVG JavaScript missing function %q", fn)
}
}
// Tooltip anchor elements must exist.
for _, id := range []string{"tt", "ttbg", "tttl", "ttbd"} {
if !strings.Contains(svg, `id="`+id+`"`) {
t.Errorf("SVG missing element id=%q", id)
}
}
}
func TestGenerateRankHistorySVG_EmptySummaries(t *testing.T) {
t.Parallel()
svg := GenerateRankHistorySVG([]ProjectSummary{})
// Should still produce a valid (empty-data) SVG with the subtitle showing 0 projects.
if !strings.Contains(svg, "