Native Wiki Generation
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
package topdata
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestBuildNativeGeneratesAndSkipsWikiPages(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "skills"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "base.json"), `{
|
||||
"output": "skills.2da",
|
||||
"columns": ["Label", "Name", "Description", "HideFromLevelUp", "Untrained", "KeyAbility", "ArmorCheckPenalty", "Constant"],
|
||||
"rows": [
|
||||
{
|
||||
"id": 0,
|
||||
"key": "skills:athletics",
|
||||
"Label": "Athletics",
|
||||
"Name": {"tlk": {"key": "skills:athletics.name", "text": "Athletics"}},
|
||||
"Description": {"tlk": {"key": "skills:athletics.description", "text": "Ability: Strength.\n\nUses:\n- Climb\n- Swim"}},
|
||||
"HideFromLevelUp": "0",
|
||||
"Untrained": "1",
|
||||
"KeyAbility": "STR",
|
||||
"ArmorCheckPenalty": "1",
|
||||
"Constant": "SKILL_ATHLETICS"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "lock.json"), `{"skills:athletics":0}`+"\n")
|
||||
|
||||
proj := testProject(root)
|
||||
proj.Config.TopData.ReferenceBuilder = ""
|
||||
|
||||
result, err := BuildNative(proj, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
if result.WikiPages != 1 {
|
||||
t.Fatalf("expected one generated entity page, got %d", result.WikiPages)
|
||||
}
|
||||
pagePath := filepath.Join(root, "topdata", ".wiki", "pages", "skills", "athletics.txt")
|
||||
got, err := os.ReadFile(pagePath)
|
||||
if err != nil {
|
||||
t.Fatalf("read generated page: %v", err)
|
||||
}
|
||||
text := string(got)
|
||||
if !strings.Contains(text, "====== Athletics ======") || !strings.Contains(text, "This skill is unchanged from vanilla.") {
|
||||
t.Fatalf("unexpected generated page:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "Ability: Strength.") || !strings.Contains(text, " * Climb") {
|
||||
t.Fatalf("expected description to be rendered into wiki page:\n%s", text)
|
||||
}
|
||||
statusPath := filepath.Join(root, "topdata", ".wiki", "pages", "meta", "wikistatus.txt")
|
||||
statusRaw, err := os.ReadFile(statusPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read status page: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(statusRaw), "**Vanilla:** 1\\\\") {
|
||||
t.Fatalf("expected wiki status summary to count vanilla page:\n%s", string(statusRaw))
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(root, "topdata", ".wiki", "state.json")); err != nil {
|
||||
t.Fatalf("expected state file after first build: %v", err)
|
||||
}
|
||||
stateBefore, err := loadWikiState(filepath.Join(root, "topdata", ".wiki", "state.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("read state before second build: %v", err)
|
||||
}
|
||||
digestBefore, err := computeWikiSourceDigest(filepath.Join(root, "topdata"))
|
||||
if err != nil {
|
||||
t.Fatalf("compute digest before second build: %v", err)
|
||||
}
|
||||
if stateBefore.Digest != digestBefore {
|
||||
t.Fatalf("expected state digest to match current digest before second build, got state=%s current=%s", stateBefore.Digest, digestBefore)
|
||||
}
|
||||
|
||||
second, err := BuildNative(proj, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("second BuildNative failed: %v", err)
|
||||
}
|
||||
if second.WikiPages != 1 {
|
||||
t.Fatalf("expected a single generated skill wiki page after rebuild, got %d", second.WikiPages)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildNativeRegeneratesWikiWhenTLKTextChanges(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "skills"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
basePath := filepath.Join(root, "topdata", "data", "skills", "base.json")
|
||||
writeFile(t, basePath, `{
|
||||
"output": "skills.2da",
|
||||
"columns": ["Label", "Name", "Description", "HideFromLevelUp", "Untrained", "KeyAbility", "ArmorCheckPenalty", "Constant"],
|
||||
"rows": [
|
||||
{
|
||||
"id": 0,
|
||||
"key": "skills:athletics",
|
||||
"Label": "Athletics",
|
||||
"Name": {"tlk": {"key": "skills:athletics.name", "text": "Athletics"}},
|
||||
"Description": {"tlk": {"key": "skills:athletics.description", "text": "Original text."}},
|
||||
"HideFromLevelUp": "0",
|
||||
"Untrained": "1",
|
||||
"KeyAbility": "STR",
|
||||
"ArmorCheckPenalty": "1",
|
||||
"Constant": "SKILL_ATHLETICS"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "lock.json"), `{"skills:athletics":0}`+"\n")
|
||||
|
||||
proj := testProject(root)
|
||||
proj.Config.TopData.ReferenceBuilder = ""
|
||||
|
||||
if _, err := BuildNative(proj, nil); err != nil {
|
||||
t.Fatalf("initial BuildNative failed: %v", err)
|
||||
}
|
||||
writeFile(t, basePath, `{
|
||||
"output": "skills.2da",
|
||||
"columns": ["Label", "Name", "Description", "HideFromLevelUp", "Untrained", "KeyAbility", "ArmorCheckPenalty", "Constant"],
|
||||
"rows": [
|
||||
{
|
||||
"id": 0,
|
||||
"key": "skills:athletics",
|
||||
"Label": "Athletics",
|
||||
"Name": {"tlk": {"key": "skills:athletics.name", "text": "Athletics"}},
|
||||
"Description": {"tlk": {"key": "skills:athletics.description", "text": "Updated text."}},
|
||||
"HideFromLevelUp": "0",
|
||||
"Untrained": "1",
|
||||
"KeyAbility": "STR",
|
||||
"ArmorCheckPenalty": "1",
|
||||
"Constant": "SKILL_ATHLETICS"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
|
||||
if _, err := BuildNative(proj, nil); err != nil {
|
||||
t.Fatalf("BuildNative after text change failed: %v", err)
|
||||
}
|
||||
pagePath := filepath.Join(root, "topdata", ".wiki", "pages", "skills", "athletics.txt")
|
||||
got, err := os.ReadFile(pagePath)
|
||||
if err != nil {
|
||||
t.Fatalf("read regenerated page: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(got), "Updated text.") {
|
||||
t.Fatalf("expected regenerated page to contain updated description:\n%s", string(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPackageIgnoresWikiSourcesForFreshness(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "skills"))
|
||||
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "base.json"), `{
|
||||
"output": "skills.2da",
|
||||
"columns": ["Label", "Name", "Description", "HideFromLevelUp", "Untrained", "KeyAbility", "ArmorCheckPenalty", "Constant"],
|
||||
"rows": [
|
||||
{
|
||||
"id": 0,
|
||||
"key": "skills:athletics",
|
||||
"Label": "Athletics",
|
||||
"Name": {"tlk": {"key": "skills:athletics.name", "text": "Athletics"}},
|
||||
"Description": {"tlk": {"key": "skills:athletics.description", "text": "Skill text."}},
|
||||
"HideFromLevelUp": "0",
|
||||
"Untrained": "1",
|
||||
"KeyAbility": "STR",
|
||||
"ArmorCheckPenalty": "1",
|
||||
"Constant": "SKILL_ATHLETICS"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(root, "topdata", "data", "skills", "lock.json"), `{"skills:athletics":0}`+"\n")
|
||||
|
||||
proj := testProject(root)
|
||||
proj.Config.TopData.ReferenceBuilder = ""
|
||||
|
||||
if _, err := BuildNative(proj, nil); err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
|
||||
pagePath := filepath.Join(root, "topdata", ".wiki", "pages", "skills", "athletics.txt")
|
||||
newTime := time.Now().Add(2 * time.Second)
|
||||
if err := os.Chtimes(pagePath, newTime, newTime); err != nil {
|
||||
t.Fatalf("touch wiki page: %v", err)
|
||||
}
|
||||
|
||||
if _, err := BuildPackage(proj, nil); err != nil {
|
||||
t.Fatalf("expected wiki output to be ignored for freshness, got %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user