Files
openclaw/scripts/docs-i18n/relocalize_test.go
Mason 9b0ea7c579 docs: relocalize stale locale links (#61796)
* docs: relocalize stale locale links

* docs: unify locale link postprocessing

* docs: preserve relocalized frontmatter

* docs: relocalize partial docs runs

* docs: scope locale link postprocessing

* docs: continue scoped relocalization

* docs: drain parallel i18n results

* docs: add i18n pipeline link regression tests

* docs: clarify i18n pipeline regression test intent

* docs: update provider references in i18n tests to use example-provider

* fix: note docs i18n link relocalization

* docs: rephrase gateway local ws sentence
2026-04-06 22:37:35 +08:00

221 lines
6.9 KiB
Go

package main
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestPostprocessLocalizedDocsFixesStaleLinksAfterLaterPagesExist(t *testing.T) {
t.Parallel()
docsRoot := t.TempDir()
writeFile(t, filepath.Join(docsRoot, "docs.json"), `{"redirects":[]}`)
writeFile(t, filepath.Join(docsRoot, "gateway", "index.md"), "# Gateway\n")
writeFile(t, filepath.Join(docsRoot, "gateway", "troubleshooting.md"), "# Troubleshooting\n")
writeFile(t, filepath.Join(docsRoot, "zh-CN", "gateway", "index.md"), stringsJoin(
"---",
"title: 网关",
"x-i18n:",
" source_hash: test",
"---",
"",
"See [Troubleshooting](/gateway/troubleshooting).",
))
writeFile(t, filepath.Join(docsRoot, "zh-CN", "gateway", "troubleshooting.md"), stringsJoin(
"---",
"title: 故障排除",
"x-i18n:",
" source_hash: test",
"---",
"",
"# 故障排除",
))
if err := postprocessLocalizedDocs(docsRoot, "zh-CN", []string{
filepath.Join(docsRoot, "zh-CN", "gateway", "index.md"),
filepath.Join(docsRoot, "zh-CN", "gateway", "troubleshooting.md"),
}); err != nil {
t.Fatalf("postprocessLocalizedDocs failed: %v", err)
}
got := mustReadFile(t, filepath.Join(docsRoot, "zh-CN", "gateway", "index.md"))
if !strings.Contains(got, "---\ntitle: 网关\nx-i18n:\n source_hash: test\n---\n\n") {
t.Fatalf("front matter corrupted after rewrite:\n%s", got)
}
want := "See [Troubleshooting](/zh-CN/gateway/troubleshooting)."
if !containsLine(got, want) {
t.Fatalf("expected rewritten localized link %q in output:\n%s", want, got)
}
}
func TestPostprocessLocalizedDocsRewritesPublishedPageLinksForEachLocale(t *testing.T) {
t.Parallel()
tests := []struct {
name string
lang string
title string
wantPrefix string
}{
{name: "zh-CN", lang: "zh-CN", title: "网关", wantPrefix: "/zh-CN"},
{name: "ja-JP", lang: "ja-JP", title: "ゲートウェイ", wantPrefix: "/ja-JP"},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
docsRoot := t.TempDir()
writeFile(t, filepath.Join(docsRoot, "docs.json"), `{"redirects":[]}`)
writeFile(t, filepath.Join(docsRoot, "gateway", "index.md"), "# Gateway\n")
writeFile(t, filepath.Join(docsRoot, "gateway", "troubleshooting.md"), "# Troubleshooting\n")
writeFile(t, filepath.Join(docsRoot, "providers", "example-provider.md"), "# Example provider\n")
writeFile(t, filepath.Join(docsRoot, tt.lang, "gateway", "troubleshooting.md"), "# Localized troubleshooting\n")
writeFile(t, filepath.Join(docsRoot, tt.lang, "providers", "example-provider.md"), "# Localized example provider\n")
pagePath := filepath.Join(docsRoot, tt.lang, "gateway", "index.md")
writeFile(t, pagePath, stringsJoin(
"---",
"title: "+tt.title,
"x-i18n:",
" source_hash: test",
"---",
"",
"See [Troubleshooting](/gateway/troubleshooting).",
"",
"See [Example provider](/providers/example-provider).",
"",
`<Card href="/gateway/troubleshooting" title="Troubleshooting" />`,
`<Card href="`+tt.wantPrefix+`/providers/example-provider" title="Example provider" />`,
))
if err := postprocessLocalizedDocs(docsRoot, tt.lang, []string{pagePath}); err != nil {
t.Fatalf("postprocessLocalizedDocs failed: %v", err)
}
got := mustReadFile(t, pagePath)
expectedLinks := []string{
"See [Troubleshooting](" + tt.wantPrefix + "/gateway/troubleshooting).",
"See [Example provider](" + tt.wantPrefix + "/providers/example-provider).",
`<Card href="` + tt.wantPrefix + `/gateway/troubleshooting" title="Troubleshooting" />`,
`<Card href="` + tt.wantPrefix + `/providers/example-provider" title="Example provider" />`,
}
for _, want := range expectedLinks {
if !containsLine(got, want) {
t.Fatalf("expected rewritten link %q in output:\n%s", want, got)
}
}
})
}
}
func TestPostprocessLocalizedDocsOnlyTouchesScopedFiles(t *testing.T) {
t.Parallel()
docsRoot := t.TempDir()
writeFile(t, filepath.Join(docsRoot, "docs.json"), `{"redirects":[]}`)
writeFile(t, filepath.Join(docsRoot, "gateway", "troubleshooting.md"), "# Troubleshooting\n")
writeFile(t, filepath.Join(docsRoot, "zh-CN", "gateway", "troubleshooting.md"), "# 故障排除\n")
scopedPath := filepath.Join(docsRoot, "zh-CN", "gateway", "index.md")
unscopedPath := filepath.Join(docsRoot, "zh-CN", "help", "index.md")
writeFile(t, scopedPath, stringsJoin(
"---",
"title: 网关",
"---",
"",
"See [Troubleshooting](/gateway/troubleshooting).",
))
writeFile(t, unscopedPath, stringsJoin(
"---",
"title: 帮助",
"---",
"",
"See [Troubleshooting](/gateway/troubleshooting).",
))
beforeUnscoped := mustReadFile(t, unscopedPath)
if err := postprocessLocalizedDocs(docsRoot, "zh-CN", []string{scopedPath}); err != nil {
t.Fatalf("postprocessLocalizedDocs failed: %v", err)
}
gotScoped := mustReadFile(t, scopedPath)
if !containsLine(gotScoped, "See [Troubleshooting](/zh-CN/gateway/troubleshooting).") {
t.Fatalf("expected scoped file rewrite, got:\n%s", gotScoped)
}
afterUnscoped := mustReadFile(t, unscopedPath)
if afterUnscoped != beforeUnscoped {
t.Fatalf("expected unscoped file to remain unchanged\nbefore:\n%s\nafter:\n%s", beforeUnscoped, afterUnscoped)
}
}
func TestPostprocessLocalizedDocsContinuesAfterUnchangedFile(t *testing.T) {
t.Parallel()
docsRoot := t.TempDir()
writeFile(t, filepath.Join(docsRoot, "docs.json"), `{"redirects":[]}`)
writeFile(t, filepath.Join(docsRoot, "gateway", "troubleshooting.md"), "# Troubleshooting\n")
writeFile(t, filepath.Join(docsRoot, "zh-CN", "gateway", "troubleshooting.md"), "# 故障排除\n")
unchangedPath := filepath.Join(docsRoot, "zh-CN", "gateway", "already-localized.md")
needsRewritePath := filepath.Join(docsRoot, "zh-CN", "gateway", "index.md")
writeFile(t, unchangedPath, stringsJoin(
"---",
"title: 已本地化",
"---",
"",
"See [Troubleshooting](/zh-CN/gateway/troubleshooting).",
))
writeFile(t, needsRewritePath, stringsJoin(
"---",
"title: 网关",
"---",
"",
"See [Troubleshooting](/gateway/troubleshooting).",
))
if err := postprocessLocalizedDocs(docsRoot, "zh-CN", []string{unchangedPath, needsRewritePath}); err != nil {
t.Fatalf("postprocessLocalizedDocs failed: %v", err)
}
got := mustReadFile(t, needsRewritePath)
if !containsLine(got, "See [Troubleshooting](/zh-CN/gateway/troubleshooting).") {
t.Fatalf("expected later file rewrite after unchanged file, got:\n%s", got)
}
}
func stringsJoin(lines ...string) string {
result := ""
for i, line := range lines {
if i > 0 {
result += "\n"
}
result += line
}
return result
}
func mustReadFile(t *testing.T, path string) string {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read failed for %s: %v", path, err)
}
return string(data)
}
func containsLine(text, want string) bool {
for _, line := range strings.Split(text, "\n") {
if line == want {
return true
}
}
return false
}