Defining list length in Template
Test don't care about list lenght
This commit is contained in:
@@ -21,15 +21,15 @@ type EqWaffe struct {
|
||||
BamortCharTrait
|
||||
Magisch
|
||||
Beschreibung string `json:"beschreibung"`
|
||||
Abwb int `json:"abwb"`
|
||||
Anb int `json:"anb"`
|
||||
Abwb int `json:"abwb"` // Abwehrbonus
|
||||
Anb int `json:"anb"` // Angriffsbonus
|
||||
Anzahl int `json:"anzahl"`
|
||||
BeinhaltetIn string `json:"beinhaltet_in"`
|
||||
ContainedIn uint `json:"contained_in"`
|
||||
ContainerType string `json:"container_type"`
|
||||
Gewicht float64 `json:"gewicht"`
|
||||
NameFuerSpezialisierung string `json:"nameFuerSpezialisierung"`
|
||||
Schb int `json:"schb"`
|
||||
Schb int `json:"schb"` // Schadensbonus
|
||||
Wert float64 `json:"wert"`
|
||||
}
|
||||
|
||||
|
||||
@@ -81,10 +81,30 @@ func TestTemplateWithEmptyRows(t *testing.T) {
|
||||
t.Fatalf("Failed to render template: %v", err)
|
||||
}
|
||||
|
||||
// Get expected skill capacity from template
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
var page1Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page1_stats.html" {
|
||||
page1Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if page1Template == nil {
|
||||
t.Fatal("page1_stats.html template not found")
|
||||
}
|
||||
var col1Capacity int
|
||||
for i := range page1Template.Metadata.Blocks {
|
||||
if page1Template.Metadata.Blocks[i].Name == "skills_column1" {
|
||||
col1Capacity = page1Template.Metadata.Blocks[i].MaxItems
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Count the number of <tr> tags in skills table
|
||||
// Should have 29 rows (2 filled + 27 empty)
|
||||
// Should have col1Capacity rows (2 filled + remaining empty)
|
||||
trCount := strings.Count(html, "<tr><td>")
|
||||
if trCount < 29 {
|
||||
t.Errorf("Expected at least 29 skill rows in HTML, got %d", trCount)
|
||||
if trCount < col1Capacity {
|
||||
t.Errorf("Expected at least %d skill rows in HTML (from template), got %d", col1Capacity, trCount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,17 +150,19 @@ func TestIntegration_TemplateMetadata(t *testing.T) {
|
||||
t.Fatalf("Failed to load templates: %v", err)
|
||||
}
|
||||
|
||||
// Load template set to get expected values from actual template files
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
|
||||
// Act & Assert - Check each template has metadata
|
||||
testCases := []struct {
|
||||
template string
|
||||
expectedBlock string
|
||||
expectedMax int
|
||||
}{
|
||||
{"page1_stats.html", "skills_column1", 29},
|
||||
{"page2_play.html", "skills_learned", 17}, // From template: MAX: 17
|
||||
{"page3_spell.html", "spells_left", 15}, // From template: MAX: 15
|
||||
{"page3_spell.html", "spells_right", 10}, // From template: MAX: 10
|
||||
{"page4_equip.html", "equipment_worn", 10},
|
||||
{"page1_stats.html", "skills_column1"},
|
||||
{"page2_play.html", "skills_learned"},
|
||||
{"page3_spell.html", "spells_left"},
|
||||
{"page3_spell.html", "spells_right"},
|
||||
{"page4_equip.html", "equipment_worn"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -176,9 +178,23 @@ func TestIntegration_TemplateMetadata(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
if block.MaxItems != tc.expectedMax {
|
||||
t.Errorf("Template %s block %s: expected max %d, got %d",
|
||||
tc.template, tc.expectedBlock, tc.expectedMax, block.MaxItems)
|
||||
// Get expected value from template set
|
||||
var expectedMax int
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == tc.template {
|
||||
for j := range templateSet.Templates[i].Metadata.Blocks {
|
||||
if templateSet.Templates[i].Metadata.Blocks[j].Name == tc.expectedBlock {
|
||||
expectedMax = templateSet.Templates[i].Metadata.Blocks[j].MaxItems
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if block.MaxItems != expectedMax {
|
||||
t.Errorf("Template %s block %s: expected max %d (from template), got %d",
|
||||
tc.template, tc.expectedBlock, expectedMax, block.MaxItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,14 +281,28 @@ func TestIntegration_PaginationWithPDF(t *testing.T) {
|
||||
|
||||
t.Logf("Successfully generated page 1 PDF with %d skills, size: %d bytes", len(pageData.Skills), len(pdfBytes))
|
||||
|
||||
// Verify second page has remaining skills (94 total - 58 from page 1 = 36 remaining)
|
||||
// But with 29+29 capacity, it will be 29+13 = 42 on page 2
|
||||
// Verify second page has remaining skills
|
||||
// Get expected capacity from template (reuse templateSet from above)
|
||||
var page1Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page1_stats.html" {
|
||||
page1Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
col1Block := GetBlockByName(page1Template.Metadata.Blocks, "skills_column1")
|
||||
col2Block := GetBlockByName(page1Template.Metadata.Blocks, "skills_column2")
|
||||
expectedPage1Capacity := col1Block.MaxItems + col2Block.MaxItems
|
||||
|
||||
col1Page2 := pages[1].Data["skills_column1"].([]SkillViewModel)
|
||||
col2Page2 := pages[1].Data["skills_column2"].([]SkillViewModel)
|
||||
totalPage2 := len(col1Page2) + len(col2Page2)
|
||||
|
||||
if totalPage2 != 42 { // 100 total - 58 from page 1 = 42 remaining
|
||||
t.Errorf("Expected 42 skills on page 2, got %d", totalPage2)
|
||||
expectedPage2 := 100 - expectedPage1Capacity // 100 total - capacity from page 1
|
||||
|
||||
if totalPage2 != expectedPage2 {
|
||||
t.Errorf("Expected %d skills on page 2 (100 total - %d from page 1), got %d", expectedPage2, expectedPage1Capacity, totalPage2)
|
||||
}
|
||||
|
||||
t.Logf("Page 2 would have %d skills distributed across columns", totalPage2)
|
||||
@@ -280,7 +310,21 @@ func TestIntegration_PaginationWithPDF(t *testing.T) {
|
||||
|
||||
// TestIntegration_MultiPageSpellList tests spell pagination across multiple pages
|
||||
func TestIntegration_MultiPageSpellList(t *testing.T) {
|
||||
// Arrange - Create 30 spells (will need 2 pages with 24 capacity each)
|
||||
// Get expected capacity from template
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
var page3Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page3_spell.html" {
|
||||
page3Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
spellsLeftBlock := GetBlockByName(page3Template.Metadata.Blocks, "spells_left")
|
||||
spellsRightBlock := GetBlockByName(page3Template.Metadata.Blocks, "spells_right")
|
||||
expectedSpellCapacity := spellsLeftBlock.MaxItems + spellsRightBlock.MaxItems
|
||||
|
||||
// Arrange - Create 30 spells
|
||||
spells := make([]SpellViewModel, 30)
|
||||
for i := 0; i < 30; i++ {
|
||||
spells[i] = SpellViewModel{
|
||||
@@ -293,7 +337,6 @@ func TestIntegration_MultiPageSpellList(t *testing.T) {
|
||||
}
|
||||
|
||||
// Create paginator
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
paginator := NewPaginator(templateSet)
|
||||
|
||||
// Paginate spells
|
||||
@@ -302,21 +345,26 @@ func TestIntegration_MultiPageSpellList(t *testing.T) {
|
||||
t.Fatalf("Failed to paginate spells: %v", err)
|
||||
}
|
||||
|
||||
// With 25 capacity (15+10), 30 spells should need 2 pages
|
||||
// Calculate expected pages
|
||||
expectedPages := (30 + expectedSpellCapacity - 1) / expectedSpellCapacity // Ceiling division
|
||||
|
||||
// Verify distribution
|
||||
// With 15+10 capacity, 30 spells should need 2 pages
|
||||
if len(pages) != 2 {
|
||||
t.Fatalf("Expected 2 pages for 30 spells, got %d", len(pages))
|
||||
if len(pages) != expectedPages {
|
||||
t.Fatalf("Expected %d pages for 30 spells (capacity %d), got %d", expectedPages, expectedSpellCapacity, len(pages))
|
||||
}
|
||||
|
||||
// Page 1: 15 (left) + 10 (right) = 25 spells
|
||||
// Page 1 should have min(30, capacity) spells
|
||||
leftPage1 := pages[0].Data["spells_left"].([]SpellViewModel)
|
||||
rightPage1 := pages[0].Data["spells_right"].([]SpellViewModel)
|
||||
totalPage1 := len(leftPage1) + len(rightPage1)
|
||||
|
||||
if totalPage1 != 25 {
|
||||
t.Errorf("Expected 25 spells on page 1 (15+10), got %d", totalPage1)
|
||||
expectedPage1 := expectedSpellCapacity
|
||||
if 30 < expectedSpellCapacity {
|
||||
expectedPage1 = 30
|
||||
}
|
||||
|
||||
if totalPage1 != expectedPage1 {
|
||||
t.Errorf("Expected %d spells on page 1 (capacity %d+%d), got %d", expectedPage1, spellsLeftBlock.MaxItems, spellsRightBlock.MaxItems, totalPage1)
|
||||
}
|
||||
|
||||
t.Logf("Successfully distributed 30 spells: Page 1 has %d (left %d, right %d)", totalPage1, len(leftPage1), len(rightPage1))
|
||||
|
||||
@@ -32,20 +32,38 @@ func TestPreparePaginatedPageData_Page1Stats(t *testing.T) {
|
||||
t.Error("SkillsColumn2 is empty")
|
||||
}
|
||||
|
||||
// Check capacities (MAX: 29 each)
|
||||
if len(pageData.SkillsColumn1) > 29 {
|
||||
t.Errorf("SkillsColumn1 exceeds capacity: got %d, max 29", len(pageData.SkillsColumn1))
|
||||
// Get capacities from template
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
var page1Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page1_stats.html" {
|
||||
page1Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
var col1MaxItems, col2MaxItems int
|
||||
for i := range page1Template.Metadata.Blocks {
|
||||
if page1Template.Metadata.Blocks[i].Name == "skills_column1" {
|
||||
col1MaxItems = page1Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page1Template.Metadata.Blocks[i].Name == "skills_column2" {
|
||||
col2MaxItems = page1Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
|
||||
if len(pageData.SkillsColumn2) > 29 {
|
||||
t.Errorf("SkillsColumn2 exceeds capacity: got %d, max 29", len(pageData.SkillsColumn2))
|
||||
// Check capacities (from template)
|
||||
if len(pageData.SkillsColumn1) > col1MaxItems {
|
||||
t.Errorf("SkillsColumn1 exceeds capacity: got %d, max %d (from template)", len(pageData.SkillsColumn1), col1MaxItems)
|
||||
}
|
||||
|
||||
if len(pageData.SkillsColumn2) > col2MaxItems {
|
||||
t.Errorf("SkillsColumn2 exceeds capacity: got %d, max %d (from template)", len(pageData.SkillsColumn2), col2MaxItems)
|
||||
}
|
||||
|
||||
// Verify skills are split correctly
|
||||
totalPaginated := len(pageData.SkillsColumn1) + len(pageData.SkillsColumn2)
|
||||
expectedTotal := 58 // 29 + 29
|
||||
expectedTotal := col1MaxItems + col2MaxItems
|
||||
if totalPaginated > expectedTotal {
|
||||
t.Errorf("Total paginated skills exceeds capacity: got %d, max %d", totalPaginated, expectedTotal)
|
||||
t.Errorf("Total paginated skills exceeds capacity: got %d, max %d (from template)", totalPaginated, expectedTotal)
|
||||
}
|
||||
|
||||
t.Logf("Column1: %d skills, Column2: %d skills (total: %d)",
|
||||
@@ -53,6 +71,24 @@ func TestPreparePaginatedPageData_Page1Stats(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSplitSkillsForColumns(t *testing.T) {
|
||||
// Get actual column capacities from template
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
var page1Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page1_stats.html" {
|
||||
page1Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
var col1MaxItems, col2MaxItems int
|
||||
for i := range page1Template.Metadata.Blocks {
|
||||
if page1Template.Metadata.Blocks[i].Name == "skills_column1" {
|
||||
col1MaxItems = page1Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page1Template.Metadata.Blocks[i].Name == "skills_column2" {
|
||||
col2MaxItems = page1Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
skills int
|
||||
@@ -64,42 +100,42 @@ func TestSplitSkillsForColumns(t *testing.T) {
|
||||
{
|
||||
name: "few skills - only column 1",
|
||||
skills: 10,
|
||||
col1Max: 29,
|
||||
col2Max: 29,
|
||||
col1Max: col1MaxItems,
|
||||
col2Max: col2MaxItems,
|
||||
wantCol1: 10,
|
||||
wantCol2: 0,
|
||||
},
|
||||
{
|
||||
name: "exactly column 1 capacity",
|
||||
skills: 29,
|
||||
col1Max: 29,
|
||||
col2Max: 29,
|
||||
wantCol1: 29,
|
||||
skills: col1MaxItems,
|
||||
col1Max: col1MaxItems,
|
||||
col2Max: col2MaxItems,
|
||||
wantCol1: col1MaxItems,
|
||||
wantCol2: 0,
|
||||
},
|
||||
{
|
||||
name: "overflow to column 2",
|
||||
skills: 40,
|
||||
col1Max: 29,
|
||||
col2Max: 29,
|
||||
wantCol1: 29,
|
||||
skills: col1MaxItems + 11,
|
||||
col1Max: col1MaxItems,
|
||||
col2Max: col2MaxItems,
|
||||
wantCol1: col1MaxItems,
|
||||
wantCol2: 11,
|
||||
},
|
||||
{
|
||||
name: "both columns full",
|
||||
skills: 58,
|
||||
col1Max: 29,
|
||||
col2Max: 29,
|
||||
wantCol1: 29,
|
||||
wantCol2: 29,
|
||||
skills: col1MaxItems + col2MaxItems,
|
||||
col1Max: col1MaxItems,
|
||||
col2Max: col2MaxItems,
|
||||
wantCol1: col1MaxItems,
|
||||
wantCol2: col2MaxItems,
|
||||
},
|
||||
{
|
||||
name: "more than both columns - truncate",
|
||||
skills: 70,
|
||||
col1Max: 29,
|
||||
col2Max: 29,
|
||||
wantCol1: 29,
|
||||
wantCol2: 29,
|
||||
skills: col1MaxItems + col2MaxItems + 12,
|
||||
col1Max: col1MaxItems,
|
||||
col2Max: col2MaxItems,
|
||||
wantCol1: col1MaxItems,
|
||||
wantCol2: col2MaxItems,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package pdfrender
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -83,7 +84,7 @@ func TestPaginateSkills_SinglePage(t *testing.T) {
|
||||
t.Errorf("Expected page number 1, got %d", page.PageNumber)
|
||||
}
|
||||
|
||||
// Column 1 should have all 10 skills (max 32)
|
||||
// Column 1 should have all 10 skills
|
||||
col1Data, ok := page.Data["skills_column1"].([]SkillViewModel)
|
||||
if !ok {
|
||||
t.Fatal("skills_column1 data not found or wrong type")
|
||||
@@ -107,7 +108,17 @@ func TestPaginateSkills_MultiColumn(t *testing.T) {
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
paginator := NewPaginator(templateSet)
|
||||
|
||||
// Create 40 skills - should fill first column (32) and spill to second (8)
|
||||
// Get expected capacity from template
|
||||
var page1Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page1_stats.html" {
|
||||
page1Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
col1Block := GetBlockByName(page1Template.Metadata.Blocks, "skills_column1")
|
||||
|
||||
// Create 40 skills - should fill first column and spill to second
|
||||
skills := make([]SkillViewModel, 40)
|
||||
for i := 0; i < 40; i++ {
|
||||
skills[i] = SkillViewModel{Name: "Skill" + string(rune(i))}
|
||||
@@ -127,16 +138,17 @@ func TestPaginateSkills_MultiColumn(t *testing.T) {
|
||||
|
||||
page := pages[0]
|
||||
|
||||
// Column 1 should have 29 skills
|
||||
// Column 1 should have max capacity skills from template
|
||||
col1Data := page.Data["skills_column1"].([]SkillViewModel)
|
||||
if len(col1Data) != 29 {
|
||||
t.Errorf("Expected 29 skills in column 1, got %d", len(col1Data))
|
||||
if len(col1Data) != col1Block.MaxItems {
|
||||
t.Errorf("Expected %d skills in column 1 (from template), got %d", col1Block.MaxItems, len(col1Data))
|
||||
}
|
||||
|
||||
// Column 2 should have 11 skills (40 total - 29 in col1)
|
||||
// Column 2 should have remaining skills
|
||||
col2Data := page.Data["skills_column2"].([]SkillViewModel)
|
||||
if len(col2Data) != 11 {
|
||||
t.Errorf("Expected 11 skills in column 2, got %d", len(col2Data))
|
||||
expectedCol2 := 40 - col1Block.MaxItems
|
||||
if len(col2Data) != expectedCol2 {
|
||||
t.Errorf("Expected %d skills in column 2 (40 total - %d in col1), got %d", expectedCol2, col1Block.MaxItems, len(col2Data))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,26 +175,46 @@ func TestPaginateSkills_MultiPage(t *testing.T) {
|
||||
t.Fatalf("Expected 2 pages, got %d", len(pages))
|
||||
}
|
||||
|
||||
// Page 1 should have 58 skills (29 + 29)
|
||||
// Get column capacities from template (reuse templateSet from above)
|
||||
var page1Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page1_stats.html" {
|
||||
page1Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
var col1Capacity, col2Capacity int
|
||||
for i := range page1Template.Metadata.Blocks {
|
||||
if page1Template.Metadata.Blocks[i].Name == "skills_column1" {
|
||||
col1Capacity = page1Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page1Template.Metadata.Blocks[i].Name == "skills_column2" {
|
||||
col2Capacity = page1Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
|
||||
// Page 1 should have full capacity (col1 + col2)
|
||||
page1 := pages[0]
|
||||
col1Page1 := page1.Data["skills_column1"].([]SkillViewModel)
|
||||
col2Page1 := page1.Data["skills_column2"].([]SkillViewModel)
|
||||
if len(col1Page1) != 29 {
|
||||
t.Errorf("Page 1 col1: expected 29 skills, got %d", len(col1Page1))
|
||||
if len(col1Page1) != col1Capacity {
|
||||
t.Errorf("Page 1 col1: expected %d skills (template capacity), got %d", col1Capacity, len(col1Page1))
|
||||
}
|
||||
if len(col2Page1) != 29 {
|
||||
t.Errorf("Page 1 col2: expected 29 skills, got %d", len(col2Page1))
|
||||
if len(col2Page1) != col2Capacity {
|
||||
t.Errorf("Page 1 col2: expected %d skills (template capacity), got %d", col2Capacity, len(col2Page1))
|
||||
}
|
||||
|
||||
// Page 2 should have 42 skills (29 + 13) - 100 total - 58 from page 1 = 42 remaining
|
||||
// Page 2 should have remaining skills
|
||||
page2 := pages[1]
|
||||
col1Page2 := page2.Data["skills_column1"].([]SkillViewModel)
|
||||
col2Page2 := page2.Data["skills_column2"].([]SkillViewModel)
|
||||
if len(col1Page2) != 29 {
|
||||
t.Errorf("Page 2 col1: expected 29 skills, got %d", len(col1Page2))
|
||||
page1Total := col1Capacity + col2Capacity
|
||||
remainingSkills := 100 - page1Total
|
||||
if len(col1Page2) != col1Capacity {
|
||||
t.Errorf("Page 2 col1: expected %d skills (template capacity), got %d", col1Capacity, len(col1Page2))
|
||||
}
|
||||
if len(col2Page2) != 13 {
|
||||
t.Errorf("Page 2 col2: expected 13 skills, got %d", len(col2Page2))
|
||||
expectedCol2 := remainingSkills - col1Capacity
|
||||
if len(col2Page2) != expectedCol2 {
|
||||
t.Errorf("Page 2 col2: expected %d skills (remaining), got %d", expectedCol2, len(col2Page2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,36 +223,62 @@ func TestPaginateSpells_TwoColumns(t *testing.T) {
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
paginator := NewPaginator(templateSet)
|
||||
|
||||
// Create 15 spells - should fit in first column (12) with 3 in second column (12)
|
||||
spells := make([]SpellViewModel, 15)
|
||||
for i := 0; i < 15; i++ {
|
||||
spells[i] = SpellViewModel{Name: "Spell" + string(rune('A'+i))}
|
||||
// Get spell column capacities from template
|
||||
var page3Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page3_spell.html" {
|
||||
page3Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Act
|
||||
pages, err := paginator.PaginateSpells(spells, "page3_spell.html")
|
||||
|
||||
// Assert
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
var leftCapacity, rightCapacity int
|
||||
for i := range page3Template.Metadata.Blocks {
|
||||
if page3Template.Metadata.Blocks[i].Name == "spells_left" {
|
||||
leftCapacity = page3Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page3Template.Metadata.Blocks[i].Name == "spells_right" {
|
||||
rightCapacity = page3Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
totalCapacity := leftCapacity + rightCapacity
|
||||
|
||||
if len(pages) != 1 {
|
||||
t.Fatalf("Expected 1 page, got %d", len(pages))
|
||||
}
|
||||
// Create spells that fit within total capacity
|
||||
testCount := totalCapacity
|
||||
if testCount > 0 {
|
||||
spells := make([]SpellViewModel, testCount)
|
||||
for i := 0; i < testCount; i++ {
|
||||
spells[i] = SpellViewModel{Name: "Spell" + string(rune('A'+i))}
|
||||
}
|
||||
|
||||
page := pages[0]
|
||||
// Act
|
||||
pages, err := paginator.PaginateSpells(spells, "page3_spell.html")
|
||||
|
||||
// Left column should have 15 spells (all fit in 20 capacity)
|
||||
leftData := page.Data["spells_left"].([]SpellViewModel)
|
||||
if len(leftData) != 15 {
|
||||
t.Errorf("Expected 15 spells in left column, got %d", len(leftData))
|
||||
}
|
||||
// Assert
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// Right column should be empty (15 spells all fit in left)
|
||||
rightData := page.Data["spells_right"].([]SpellViewModel)
|
||||
if len(rightData) != 0 {
|
||||
t.Errorf("Expected 0 spells in right column, got %d", len(rightData))
|
||||
if len(pages) != 1 {
|
||||
t.Fatalf("Expected 1 page (capacity %d from template), got %d", totalCapacity, len(pages))
|
||||
}
|
||||
|
||||
page := pages[0]
|
||||
|
||||
// Left column should be filled first
|
||||
leftData := page.Data["spells_left"].([]SpellViewModel)
|
||||
expectedLeft := leftCapacity
|
||||
if testCount < leftCapacity {
|
||||
expectedLeft = testCount
|
||||
}
|
||||
if len(leftData) != expectedLeft {
|
||||
t.Errorf("Expected %d spells in left column (template capacity), got %d", expectedLeft, len(leftData))
|
||||
}
|
||||
|
||||
// Right column gets remainder
|
||||
rightData := page.Data["spells_right"].([]SpellViewModel)
|
||||
expectedRight := testCount - expectedLeft
|
||||
if len(rightData) != expectedRight {
|
||||
t.Errorf("Expected %d spells in right column (remaining), got %d", expectedRight, len(rightData))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +287,24 @@ func TestPaginateSpells_MultiPage(t *testing.T) {
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
paginator := NewPaginator(templateSet)
|
||||
|
||||
// Create 30 spells - should fit on 1 page (30 capacity = 20 left + 10 right)
|
||||
// Get spell column capacities from template
|
||||
var page3Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page3_spell.html" {
|
||||
page3Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
var leftCapacity, rightCapacity int
|
||||
for i := range page3Template.Metadata.Blocks {
|
||||
if page3Template.Metadata.Blocks[i].Name == "spells_left" {
|
||||
leftCapacity = page3Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page3Template.Metadata.Blocks[i].Name == "spells_right" {
|
||||
rightCapacity = page3Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
|
||||
// Create 30 spells - should span multiple pages based on template capacity
|
||||
spells := make([]SpellViewModel, 30)
|
||||
for i := 0; i < 30; i++ {
|
||||
spells[i] = SpellViewModel{Name: "Spell" + string(rune(i))}
|
||||
@@ -243,20 +318,22 @@ func TestPaginateSpells_MultiPage(t *testing.T) {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// With capacity of 15+10=25 (from template), 30 spells require 2 pages
|
||||
if len(pages) != 2 {
|
||||
t.Fatalf("Expected 2 pages, got %d", len(pages))
|
||||
// With capacity from template, 30 spells require 2 pages
|
||||
totalCapacity := leftCapacity + rightCapacity
|
||||
expectedPages := (30 + totalCapacity - 1) / totalCapacity // ceiling division
|
||||
if len(pages) != expectedPages {
|
||||
t.Fatalf("Expected %d pages (capacity %d from template), got %d", expectedPages, totalCapacity, len(pages))
|
||||
}
|
||||
|
||||
// Page 1 should have 25 spells (15 left + 10 right)
|
||||
// Page 1 should have full capacity (left + right)
|
||||
page1 := pages[0]
|
||||
leftPage1 := page1.Data["spells_left"].([]SpellViewModel)
|
||||
rightPage1 := page1.Data["spells_right"].([]SpellViewModel)
|
||||
if len(leftPage1) != 15 {
|
||||
t.Errorf("Page 1 left: expected 15 spells (template capacity), got %d", len(leftPage1))
|
||||
if len(leftPage1) != leftCapacity {
|
||||
t.Errorf("Page 1 left: expected %d spells (template capacity), got %d", leftCapacity, len(leftPage1))
|
||||
}
|
||||
if len(rightPage1) != 10 {
|
||||
t.Errorf("Page 1 right: expected 10 spells (template capacity), got %d", len(rightPage1))
|
||||
if len(rightPage1) != rightCapacity {
|
||||
t.Errorf("Page 1 right: expected %d spells (template capacity), got %d", rightCapacity, len(rightPage1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +371,30 @@ func TestPaginateWeapons_MultiPage(t *testing.T) {
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
paginator := NewPaginator(templateSet)
|
||||
|
||||
// Create 50 weapons - should span 3 pages (22 capacity per page from template)
|
||||
// Get weapon capacity from template
|
||||
var page2Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page2_play.html" {
|
||||
page2Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if page2Template == nil {
|
||||
t.Fatal("page2_play.html template not found")
|
||||
}
|
||||
var weaponsBlock *BlockMetadata
|
||||
for i := range page2Template.Metadata.Blocks {
|
||||
if page2Template.Metadata.Blocks[i].Name == "weapons_main" {
|
||||
weaponsBlock = &page2Template.Metadata.Blocks[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if weaponsBlock == nil {
|
||||
t.Fatal("weapons_main block not found")
|
||||
}
|
||||
weaponCapacity := weaponsBlock.MaxItems
|
||||
|
||||
// Create 50 weapons - should span 3 pages based on template capacity
|
||||
weapons := make([]WeaponViewModel, 50)
|
||||
for i := 0; i < 50; i++ {
|
||||
weapons[i] = WeaponViewModel{Name: "Weapon" + string(rune(i))}
|
||||
@@ -308,26 +408,24 @@ func TestPaginateWeapons_MultiPage(t *testing.T) {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if len(pages) != 3 {
|
||||
t.Fatalf("Expected 3 pages (22+22+6 from template capacity), got %d", len(pages))
|
||||
expectedPages := (50 + weaponCapacity - 1) / weaponCapacity // ceiling division
|
||||
if len(pages) != expectedPages {
|
||||
t.Fatalf("Expected %d pages (%d capacity from template), got %d", expectedPages, weaponCapacity, len(pages))
|
||||
}
|
||||
|
||||
// Page 1 should have 22 weapons
|
||||
page1Weapons := pages[0].Data["weapons_main"].([]WeaponViewModel)
|
||||
if len(page1Weapons) != 22 {
|
||||
t.Errorf("Page 1: expected 22 weapons (template capacity), got %d", len(page1Weapons))
|
||||
// First pages should have weaponCapacity weapons each
|
||||
for i := 0; i < expectedPages-1; i++ {
|
||||
pageWeapons := pages[i].Data["weapons_main"].([]WeaponViewModel)
|
||||
if len(pageWeapons) != weaponCapacity {
|
||||
t.Errorf("Page %d: expected %d weapons (template capacity), got %d", i+1, weaponCapacity, len(pageWeapons))
|
||||
}
|
||||
}
|
||||
|
||||
// Page 2 should have 22 weapons
|
||||
page2Weapons := pages[1].Data["weapons_main"].([]WeaponViewModel)
|
||||
if len(page2Weapons) != 22 {
|
||||
t.Errorf("Page 2: expected 22 weapons (template capacity), got %d", len(page2Weapons))
|
||||
}
|
||||
|
||||
// Page 3 should have 6 weapons (remaining)
|
||||
page3Weapons := pages[2].Data["weapons_main"].([]WeaponViewModel)
|
||||
if len(page3Weapons) != 6 {
|
||||
t.Errorf("Page 3: expected 6 weapons (remaining), got %d", len(page3Weapons))
|
||||
// Last page should have remaining weapons
|
||||
remainingWeapons := 50 - ((expectedPages - 1) * weaponCapacity)
|
||||
lastPageWeapons := pages[expectedPages-1].Data["weapons_main"].([]WeaponViewModel)
|
||||
if len(lastPageWeapons) != remainingWeapons {
|
||||
t.Errorf("Last page: expected %d weapons (remaining), got %d", remainingWeapons, len(lastPageWeapons))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,6 +434,50 @@ func TestCalculatePagesNeeded(t *testing.T) {
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
paginator := NewPaginator(templateSet)
|
||||
|
||||
// Get capacities from templates
|
||||
var page1Template, page2Template, page3Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
switch templateSet.Templates[i].Metadata.Name {
|
||||
case "page1_stats.html":
|
||||
page1Template = &templateSet.Templates[i]
|
||||
case "page2_play.html":
|
||||
page2Template = &templateSet.Templates[i]
|
||||
case "page3_spell.html":
|
||||
page3Template = &templateSet.Templates[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Get skill capacity (col1 + col2)
|
||||
var skillCol1, skillCol2 int
|
||||
for i := range page1Template.Metadata.Blocks {
|
||||
if page1Template.Metadata.Blocks[i].Name == "skills_column1" {
|
||||
skillCol1 = page1Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page1Template.Metadata.Blocks[i].Name == "skills_column2" {
|
||||
skillCol2 = page1Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
skillCapacity := skillCol1 + skillCol2
|
||||
|
||||
// Get weapon capacity
|
||||
var weaponCapacity int
|
||||
for i := range page2Template.Metadata.Blocks {
|
||||
if page2Template.Metadata.Blocks[i].Name == "weapons_main" {
|
||||
weaponCapacity = page2Template.Metadata.Blocks[i].MaxItems
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Get spell capacity (col1 + col2)
|
||||
var spellCol1, spellCol2 int
|
||||
for i := range page3Template.Metadata.Blocks {
|
||||
if page3Template.Metadata.Blocks[i].Name == "spells_left" {
|
||||
spellCol1 = page3Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page3Template.Metadata.Blocks[i].Name == "spells_right" {
|
||||
spellCol2 = page3Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
spellCapacity := spellCol1 + spellCol2
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
templateName string
|
||||
@@ -344,15 +486,15 @@ func TestCalculatePagesNeeded(t *testing.T) {
|
||||
expectedPages int
|
||||
}{
|
||||
{"10 skills on page1", "page1_stats.html", "skills", 10, 1},
|
||||
{"58 skills on page1", "page1_stats.html", "skills", 58, 1}, // 29+29 = 58 fits on 1 page
|
||||
{"59 skills on page1", "page1_stats.html", "skills", 59, 2}, // 59 requires 2 pages
|
||||
{fmt.Sprintf("%d skills on page1", skillCapacity), "page1_stats.html", "skills", skillCapacity, 1},
|
||||
{fmt.Sprintf("%d skills on page1", skillCapacity+1), "page1_stats.html", "skills", skillCapacity + 1, 2},
|
||||
{"100 skills on page1", "page1_stats.html", "skills", 100, 2},
|
||||
{"10 weapons on page2", "page2_play.html", "weapons", 10, 1},
|
||||
{"22 weapons on page2", "page2_play.html", "weapons", 22, 1}, // MAX:22 from template
|
||||
{"23 weapons on page2", "page2_play.html", "weapons", 23, 2}, // exceeds capacity
|
||||
{fmt.Sprintf("%d weapons on page2", weaponCapacity), "page2_play.html", "weapons", weaponCapacity, 1},
|
||||
{fmt.Sprintf("%d weapons on page2", weaponCapacity+1), "page2_play.html", "weapons", weaponCapacity + 1, 2},
|
||||
{"10 spells on page3", "page3_spell.html", "spells", 10, 1},
|
||||
{"25 spells on page3", "page3_spell.html", "spells", 25, 1}, // 15+10 = 25 fits on 1 page (from template)
|
||||
{"26 spells on page3", "page3_spell.html", "spells", 26, 2}, // 26 requires 2 pages
|
||||
{fmt.Sprintf("%d spells on page3", spellCapacity), "page3_spell.html", "spells", spellCapacity, 1},
|
||||
{fmt.Sprintf("%d spells on page3", spellCapacity+1), "page3_spell.html", "spells", spellCapacity + 1, 2},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package pdfrender
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -34,7 +35,25 @@ func TestLoadTemplateSetFromFiles(t *testing.T) {
|
||||
t.Error("Expected blocks in page1 metadata")
|
||||
}
|
||||
|
||||
// Verify skills_column1 block
|
||||
// Verify skills_column1 block - read expected value directly from template file
|
||||
templateContent, err := os.ReadFile("../templates/Default_A4_Quer/page1_stats.html")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read template file: %v", err)
|
||||
}
|
||||
|
||||
expectedBlocks := ParseTemplateMetadata(string(templateContent))
|
||||
var expectedSkillsCol1 *BlockMetadata
|
||||
for i := range expectedBlocks {
|
||||
if expectedBlocks[i].Name == "skills_column1" {
|
||||
expectedSkillsCol1 = &expectedBlocks[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if expectedSkillsCol1 == nil {
|
||||
t.Fatal("skills_column1 block not found in template file")
|
||||
}
|
||||
|
||||
var skillsCol1 *BlockMetadata
|
||||
for i := range page1.Metadata.Blocks {
|
||||
if page1.Metadata.Blocks[i].Name == "skills_column1" {
|
||||
@@ -47,8 +66,8 @@ func TestLoadTemplateSetFromFiles(t *testing.T) {
|
||||
t.Error("skills_column1 block not found")
|
||||
} else {
|
||||
// Should match the MAX value in the template comment
|
||||
if skillsCol1.MaxItems != 29 {
|
||||
t.Errorf("Expected skills_column1 MaxItems 29 (from template), got %d", skillsCol1.MaxItems)
|
||||
if skillsCol1.MaxItems != expectedSkillsCol1.MaxItems {
|
||||
t.Errorf("Expected skills_column1 MaxItems %d (from template), got %d", expectedSkillsCol1.MaxItems, skillsCol1.MaxItems)
|
||||
}
|
||||
if skillsCol1.ListType != "skills" {
|
||||
t.Errorf("Expected ListType 'skills', got '%s'", skillsCol1.ListType)
|
||||
@@ -65,7 +84,25 @@ func TestDefaultA4QuerTemplateSet_LoadsFromFiles(t *testing.T) {
|
||||
}
|
||||
|
||||
// Verify metadata comes from template files, not hardcoded
|
||||
// Check page3_spell.html spells_left should be 20 (from template)
|
||||
// Read expected value directly from template file
|
||||
templateContent, err := os.ReadFile("../templates/Default_A4_Quer/page3_spell.html")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read template file: %v", err)
|
||||
}
|
||||
|
||||
expectedBlocks := ParseTemplateMetadata(string(templateContent))
|
||||
var expectedSpellsLeft *BlockMetadata
|
||||
for i := range expectedBlocks {
|
||||
if expectedBlocks[i].Name == "spells_left" {
|
||||
expectedSpellsLeft = &expectedBlocks[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if expectedSpellsLeft == nil {
|
||||
t.Fatal("spells_left block not found in template file")
|
||||
}
|
||||
|
||||
var page3 *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page3_spell.html" {
|
||||
@@ -89,9 +126,9 @@ func TestDefaultA4QuerTemplateSet_LoadsFromFiles(t *testing.T) {
|
||||
if spellsLeft == nil {
|
||||
t.Error("spells_left block not found")
|
||||
} else {
|
||||
// Should be 15 from the template file (<!-- BLOCK: spells_left, TYPE: spells, MAX: 15 -->)
|
||||
if spellsLeft.MaxItems != 15 {
|
||||
t.Errorf("Expected spells_left MaxItems 15 (from template file), got %d", spellsLeft.MaxItems)
|
||||
// Should match the value from the template file
|
||||
if spellsLeft.MaxItems != expectedSpellsLeft.MaxItems {
|
||||
t.Errorf("Expected spells_left MaxItems %d (from template file), got %d", expectedSpellsLeft.MaxItems, spellsLeft.MaxItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,23 +82,46 @@ func TestGetTemplateMetadata(t *testing.T) {
|
||||
t.Fatal("Expected metadata blocks, got none")
|
||||
}
|
||||
|
||||
// Check for spells_left block (template says MAX: 15)
|
||||
// Read actual template to get expected MAX values
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
var page3Template *TemplateWithMeta
|
||||
for i := range templateSet.Templates {
|
||||
if templateSet.Templates[i].Metadata.Name == "page3_spell.html" {
|
||||
page3Template = &templateSet.Templates[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if page3Template == nil {
|
||||
t.Fatal("page3_spell.html template not found")
|
||||
}
|
||||
|
||||
// Get expected values from template
|
||||
var expectedLeftMax, expectedRightMax int
|
||||
for i := range page3Template.Metadata.Blocks {
|
||||
if page3Template.Metadata.Blocks[i].Name == "spells_left" {
|
||||
expectedLeftMax = page3Template.Metadata.Blocks[i].MaxItems
|
||||
} else if page3Template.Metadata.Blocks[i].Name == "spells_right" {
|
||||
expectedRightMax = page3Template.Metadata.Blocks[i].MaxItems
|
||||
}
|
||||
}
|
||||
|
||||
// Check for spells_left block
|
||||
leftBlock := GetBlockByName(metadata, "spells_left")
|
||||
if leftBlock == nil {
|
||||
t.Error("Expected to find 'spells_left' block")
|
||||
} else {
|
||||
if leftBlock.MaxItems != 15 {
|
||||
t.Errorf("Expected spells_left max 15 (from template), got %d", leftBlock.MaxItems)
|
||||
if leftBlock.MaxItems != expectedLeftMax {
|
||||
t.Errorf("Expected spells_left max %d (from template), got %d", expectedLeftMax, leftBlock.MaxItems)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for spells_right block (template says MAX: 10)
|
||||
// Check for spells_right block
|
||||
rightBlock := GetBlockByName(metadata, "spells_right")
|
||||
if rightBlock == nil {
|
||||
t.Error("Expected to find 'spells_right' block")
|
||||
} else {
|
||||
if rightBlock.MaxItems != 10 {
|
||||
t.Errorf("Expected spells_right max 10 (from template), got %d", rightBlock.MaxItems)
|
||||
if rightBlock.MaxItems != expectedRightMax {
|
||||
t.Errorf("Expected spells_right max %d (from template), got %d", expectedRightMax, rightBlock.MaxItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
* weapons_main list currently uses Waffenfertigkeiten (weapon skills).
|
||||
NOTE: Equipment.Weapons (EqWaffe) contains physical weapons with metadata like Abwb/Schb.
|
||||
Waffenfertigkeiten already provides EW (Fertigkeitswert) which is the skill value needed for the character sheet.
|
||||
Current implementation is correct - weapons_main shows weapon skills with their EW values.
|
||||
* The implementation is NOT correct, because the eapons_main shows weapon skills. But it should show the weapons list from the equipment
|
||||
## COMPLETED
|
||||
|
||||
* ✅ Page 2 Weapons Table now shows the following information:
|
||||
- For each Weapon a character has:
|
||||
- Its name
|
||||
- ✅ the Fertigkeitswert (EW): Waffenfertigkeit.Fertigkeitswert + Character.AngriffBonus + Weapon.Anb (if equipped)
|
||||
- ❌ TODO: the Schaden (Damage) including character's SchadenBonus and weapon's Schadensbonus
|
||||
- ❌ TODO: If it is a ranged weapon, the ranges for near, medium and far
|
||||
|
||||
Implementation notes:
|
||||
- ✅ AngriffBonus and SchadenBonus are now calculated in DerivedValueSet from character attributes
|
||||
- ✅ mapWeapons() function now:
|
||||
- Calculates EW = Waffenfertigkeit.Fertigkeitswert + Character.AngriffBonus + Weapon.Anb
|
||||
- Matches Waffenfertigkeiten with equipped Waffen by name
|
||||
- Adds weapon attack bonus (Anb) if weapon is equipped
|
||||
- ✅ Added test TestMapWeapons_WithEWCalculation to verify correct EW calculation
|
||||
- ✅ Used TDD approach: wrote failing test first, then implemented solution
|
||||
|
||||
* ✅ Template MaxItems expectations are now dynamic:
|
||||
- Tests now read MaxItems values directly from template HTML comments
|
||||
- Updated TestLoadTemplateSetFromFiles to parse templates dynamically
|
||||
- Updated TestDefaultA4QuerTemplateSet_LoadsFromFiles to use dynamic expectations
|
||||
- Updated TestPaginationUsesTemplateMetadata to read from template files
|
||||
- Tests will automatically adapt when template capacities change
|
||||
|
||||
## TODO (Remaining)
|
||||
|
||||
* Page 2 Weapons - Damage calculation:
|
||||
- Calculate and display weapon damage including:
|
||||
- Base weapon damage (from models.Weapon)
|
||||
- Character's SchadenBonus
|
||||
- Weapon's Schadensbonus (Schb from EqWaffe)
|
||||
- Format: e.g., "1W6+3" where +3 = SchadenBonus + Schb
|
||||
|
||||
* Page 2 Weapons - Ranged weapon ranges:
|
||||
- For ranged weapons (Bogen, Armbrust, Wurfwaffe), show:
|
||||
- Range for "Nah" (near)
|
||||
- Range for "Mittel" (medium)
|
||||
- Range for "Fern" (far)
|
||||
- This data should come from models.Weapon.Range or similar field
|
||||
.
|
||||
|
||||
* add 3 field to gsm_weapons that holds the ranges near, middle, far all values are measured in meters so integer seems to be a good datatype. If at least 1 of 3 values is > 0 the weapon is treated as a ranged weapon
|
||||
* add a field to gsm_weapons that holds the damage the weapon creates Damage is notated as 2W6+3
|
||||
* EqWaffe already contains the values for the bunus values we need Attack (Anb), Damage (Schb) und Defence (Abwb)
|
||||
|
||||
* currently the template fetched for rendering is set to Default_A4_Quer
|
||||
@@ -2,11 +2,23 @@ package pdfrender
|
||||
|
||||
import (
|
||||
"bamort/models"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestPaginationUsesTemplateMetadata verifies tests use actual template MAX values
|
||||
func TestPaginationUsesTemplateMetadata(t *testing.T) {
|
||||
// Read expected values directly from template file
|
||||
templateContent, err := os.ReadFile("../templates/Default_A4_Quer/page2_play.html")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read template file: %v", err)
|
||||
}
|
||||
|
||||
expectedBlocks := ParseTemplateMetadata(string(templateContent))
|
||||
expectedSkillsLearned := GetBlockByName(expectedBlocks, "skills_learned")
|
||||
expectedSkillsLanguages := GetBlockByName(expectedBlocks, "skills_languages")
|
||||
expectedWeaponsMain := GetBlockByName(expectedBlocks, "weapons_main")
|
||||
|
||||
// Load template set from actual files
|
||||
templateSet := DefaultA4QuerTemplateSet()
|
||||
|
||||
@@ -28,28 +40,39 @@ func TestPaginationUsesTemplateMetadata(t *testing.T) {
|
||||
if skillsLearned == nil {
|
||||
t.Fatal("skills_learned block not found")
|
||||
}
|
||||
if skillsLearned.MaxItems != 17 {
|
||||
t.Errorf("skills_learned: expected MAX 17 from template, got %d", skillsLearned.MaxItems)
|
||||
if expectedSkillsLearned != nil && skillsLearned.MaxItems != expectedSkillsLearned.MaxItems {
|
||||
t.Errorf("skills_learned: expected MAX %d from template, got %d", expectedSkillsLearned.MaxItems, skillsLearned.MaxItems)
|
||||
}
|
||||
|
||||
skillsLanguages := GetBlockByName(page2.Metadata.Blocks, "skills_languages")
|
||||
if skillsLanguages == nil {
|
||||
t.Fatal("skills_languages block not found")
|
||||
}
|
||||
if skillsLanguages.MaxItems != 4 {
|
||||
t.Errorf("skills_languages: expected MAX 4 from template, got %d", skillsLanguages.MaxItems)
|
||||
if expectedSkillsLanguages != nil && skillsLanguages.MaxItems != expectedSkillsLanguages.MaxItems {
|
||||
t.Errorf("skills_languages: expected MAX %d from template, got %d", expectedSkillsLanguages.MaxItems, skillsLanguages.MaxItems)
|
||||
}
|
||||
|
||||
weaponsMain := GetBlockByName(page2.Metadata.Blocks, "weapons_main")
|
||||
if weaponsMain == nil {
|
||||
t.Fatal("weapons_main block not found")
|
||||
}
|
||||
if weaponsMain.MaxItems != 22 {
|
||||
t.Errorf("weapons_main: expected MAX 22 from template, got %d", weaponsMain.MaxItems)
|
||||
if expectedWeaponsMain != nil && weaponsMain.MaxItems != expectedWeaponsMain.MaxItems {
|
||||
t.Errorf("weapons_main: expected MAX %d from template, got %d", expectedWeaponsMain.MaxItems, weaponsMain.MaxItems)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPage2PaginationWithCorrectCapacities(t *testing.T) {
|
||||
// Read expected values directly from template file
|
||||
templateContent, err := os.ReadFile("../templates/Default_A4_Quer/page2_play.html")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read template file: %v", err)
|
||||
}
|
||||
|
||||
expectedBlocks := ParseTemplateMetadata(string(templateContent))
|
||||
expectedSkillsLearned := GetBlockByName(expectedBlocks, "skills_learned")
|
||||
expectedSkillsLanguages := GetBlockByName(expectedBlocks, "skills_languages")
|
||||
expectedWeaponsMain := GetBlockByName(expectedBlocks, "weapons_main")
|
||||
|
||||
// Create test data
|
||||
viewModel := &CharacterSheetViewModel{
|
||||
Skills: []SkillViewModel{
|
||||
@@ -69,21 +92,30 @@ func TestPage2PaginationWithCorrectCapacities(t *testing.T) {
|
||||
t.Fatalf("Failed to prepare page data: %v", err)
|
||||
}
|
||||
|
||||
// Verify capacities match template (18, 5, 24)
|
||||
if len(pageData.SkillsLearned) != 17 {
|
||||
t.Errorf("SkillsLearned should be filled to 17, got %d", len(pageData.SkillsLearned))
|
||||
// Verify capacities match template values
|
||||
if expectedSkillsLearned != nil && len(pageData.SkillsLearned) != expectedSkillsLearned.MaxItems {
|
||||
t.Errorf("SkillsLearned should be filled to %d (from template), got %d", expectedSkillsLearned.MaxItems, len(pageData.SkillsLearned))
|
||||
}
|
||||
|
||||
if len(pageData.SkillsLanguage) != 4 {
|
||||
t.Errorf("SkillsLanguage should be filled to 4, got %d", len(pageData.SkillsLanguage))
|
||||
if expectedSkillsLanguages != nil && len(pageData.SkillsLanguage) != expectedSkillsLanguages.MaxItems {
|
||||
t.Errorf("SkillsLanguage should be filled to %d (from template), got %d", expectedSkillsLanguages.MaxItems, len(pageData.SkillsLanguage))
|
||||
}
|
||||
|
||||
if len(pageData.Weapons) != 22 {
|
||||
t.Errorf("Weapons should be filled to 22, got %d", len(pageData.Weapons))
|
||||
if expectedWeaponsMain != nil && len(pageData.Weapons) != expectedWeaponsMain.MaxItems {
|
||||
t.Errorf("Weapons should be filled to %d (from template), got %d", expectedWeaponsMain.MaxItems, len(pageData.Weapons))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPage3MagicItemsCapacity(t *testing.T) {
|
||||
// Read expected values directly from template file
|
||||
templateContent, err := os.ReadFile("../templates/Default_A4_Quer/page3_spell.html")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read template file: %v", err)
|
||||
}
|
||||
|
||||
expectedBlocks := ParseTemplateMetadata(string(templateContent))
|
||||
expectedMagicItems := GetBlockByName(expectedBlocks, "magic_items")
|
||||
|
||||
// Create test data with magic items
|
||||
viewModel := &CharacterSheetViewModel{
|
||||
MagicItems: []MagicItemViewModel{
|
||||
@@ -100,9 +132,9 @@ func TestPage3MagicItemsCapacity(t *testing.T) {
|
||||
t.Fatalf("Failed to prepare page data: %v", err)
|
||||
}
|
||||
|
||||
// Template says MAX: 8 for magic_items
|
||||
if len(pageData.MagicItems) != 5 {
|
||||
t.Errorf("MagicItems should be filled to 5, got %d", len(pageData.MagicItems))
|
||||
// Verify capacity matches template
|
||||
if expectedMagicItems != nil && len(pageData.MagicItems) != expectedMagicItems.MaxItems {
|
||||
t.Errorf("MagicItems should be filled to %d (from template), got %d", expectedMagicItems.MaxItems, len(pageData.MagicItems))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user