BAB tables

This commit is contained in:
2026-05-23 20:53:58 +02:00
parent 3f36ed529a
commit ed2ad4f9a0
4 changed files with 429 additions and 4 deletions
+144
View File
@@ -492,6 +492,122 @@ providers:
}
}
func TestWikiTemplateClassProgressionProviderUsesDefaultNWNAttackSequences(t *testing.T) {
ctx := &wikiContext{
wikiDataPath: "test-data.yaml",
wikiDataProviders: map[string]wikiDataProviderDefinition{
"ClassProgression": {Source: "class_progression", Levels: "1-16"},
},
}
page := wikiTemplatePage{
PageID: "classes:fighter",
Category: "classes",
Key: "classes:fighter",
Title: "Fighter",
Row: map[string]any{
"AttackBonusTable": "cls_atk_1",
},
}
got, err := ctx.renderWikiTemplateString("classes.html", `{{#each ClassProgression}}{{Level}}:{{BABValue}}:{{AttackCount}}:{{AttackSequence}}
{{/each}}`, page)
if err != nil {
t.Fatalf("render template: %v", err)
}
for _, expected := range []string{
"1:1:1:+1",
"6:6:2:+6/+1",
"11:11:3:+11/+6/+1",
"16:16:4:+16/+11/+6/+1",
} {
if !strings.Contains(got, expected) {
t.Fatalf("expected %q in rendered progression:\n%s", expected, got)
}
}
}
func TestWikiTemplateClassProgressionProviderSupportsFixedAttacksAndOverrides(t *testing.T) {
root := t.TempDir()
dataPath := filepath.Join(root, "data.yaml")
writeFile(t, dataPath, `
providers:
ClassProgression:
source: class_progression
levels: 1-12
attacks:
mode: fixed
attacks: 2
step: -5
overrides:
- classes: ["classes:fighter"]
levels: 11
attacks: 3
`+"\n")
providers, err := loadWikiDataProviders(dataPath)
if err != nil {
t.Fatalf("load data providers: %v", err)
}
ctx := &wikiContext{
wikiDataPath: dataPath,
wikiDataProviders: providers,
}
page := wikiTemplatePage{
PageID: "classes:fighter",
Category: "classes",
Key: "classes:fighter",
Title: "Fighter",
Row: map[string]any{
"AttackBonusTable": "cls_atk_1",
},
}
got, err := ctx.renderWikiTemplateString("classes.html", `{{#each ClassProgression}}{{Level}}:{{AttackCount}}:{{AttackSequence}}
{{/each}}`, page)
if err != nil {
t.Fatalf("render template: %v", err)
}
for _, expected := range []string{
"1:2:+1/-4",
"6:2:+6/+1",
"11:3:+11/+6/+1",
"12:2:+12/+7",
} {
if !strings.Contains(got, expected) {
t.Fatalf("expected %q in rendered progression:\n%s", expected, got)
}
}
}
func TestWikiTemplateCountHelperSupportsListGrammar(t *testing.T) {
ctx := &wikiContext{}
page := wikiTemplatePage{
PageID: "classes:test",
Category: "classes",
Key: "classes:test",
Title: "Test Class",
Row: map[string]any{
"AvailableFeats": []any{"One", "Two"},
},
}
got, err := ctx.renderWikiTemplateString("classes.html", `{{AvailableFeats|join:", "}} {{if(count(AvailableFeats) > 1, "become", "becomes")}} available.`, page)
if err != nil {
t.Fatalf("render plural template: %v", err)
}
if got != "One, Two become available." {
t.Fatalf("unexpected plural grammar: %q", got)
}
page.Row["AvailableFeats"] = []any{"One"}
got, err = ctx.renderWikiTemplateString("classes.html", `{{AvailableFeats|join:", "}} {{if(count(AvailableFeats) > 1, "become", "becomes")}} available.`, page)
if err != nil {
t.Fatalf("render singular template: %v", err)
}
if got != "One becomes available." {
t.Fatalf("unexpected singular grammar: %q", got)
}
}
func TestWikiDataProvidersRejectEmptyClassFeatProjectionCondition(t *testing.T) {
root := t.TempDir()
dataPath := filepath.Join(root, "data.yaml")
@@ -516,6 +632,34 @@ providers:
}
}
func TestWikiDataProvidersRejectInvalidAttackOverrideConfig(t *testing.T) {
root := t.TempDir()
dataPath := filepath.Join(root, "data.yaml")
writeFile(t, dataPath, `
providers:
ClassProgression:
source: class_progression
attacks:
mode: fixed
attacks: 2
overrides:
- classes: ["classes:fighter"]
levels: 11
attacks: 3
add: 1
`+"\n")
_, err := loadWikiDataProviders(dataPath)
if err == nil {
t.Fatal("expected invalid attack override config")
}
for _, expected := range []string{"data.yaml", "ClassProgression", "attacks", "override"} {
if !strings.Contains(err.Error(), expected) {
t.Fatalf("expected error to contain %q, got %v", expected, err)
}
}
}
func TestWikiDataProvidersRejectInvalidColumnProviderConfig(t *testing.T) {
root := t.TempDir()
dataPath := filepath.Join(root, "data.yaml")