Files
wordZero/test/template_test.go

360 lines
9.7 KiB
Go

// Package test 模板功能集成测试
package test
import (
"os"
"testing"
"github.com/ZeroHawkeye/wordZero/pkg/document"
)
// TestTemplateIntegration 模板功能集成测试
func TestTemplateIntegration(t *testing.T) {
// 确保输出目录存在
outputDir := "output"
if _, err := os.Stat(outputDir); os.IsNotExist(err) {
err = os.Mkdir(outputDir, 0755)
if err != nil {
t.Fatalf("Failed to create output directory: %v", err)
}
}
// 运行各项测试
t.Run("变量替换集成测试", testVariableReplacementIntegration)
t.Run("条件语句集成测试", testConditionalStatementsIntegration)
t.Run("循环语句集成测试", testLoopStatementsIntegration)
t.Run("结构体绑定集成测试", testStructDataBindingIntegration)
// 清理测试文件
t.Cleanup(func() {
cleanupTestFiles()
})
}
// testVariableReplacementIntegration 测试变量替换集成功能
func testVariableReplacementIntegration(t *testing.T) {
// 创建基础文档
doc := document.New()
// 添加包含模板变量的段落
doc.AddParagraph("产品信息单")
doc.AddParagraph("")
doc.AddParagraph("产品名称:{{productName}}")
doc.AddParagraph("产品价格:{{price}} 元")
doc.AddParagraph("产品数量:{{quantity}} 个")
doc.AddParagraph("是否库存充足:{{inStock}}")
doc.AddParagraph("产品描述:{{description}}")
doc.AddParagraph("更新时间:{{updateTime}}")
// 创建模板引擎并从文档创建模板
engine := document.NewTemplateEngine()
template, err := engine.LoadTemplateFromDocument("product_info", doc)
if err != nil {
t.Fatalf("Failed to load template from document: %v", err)
}
// 验证解析的变量数量
expectedVars := 6
if len(template.Variables) != expectedVars {
t.Logf("Variables found: %v", template.Variables)
}
// 创建多种类型的数据
data := document.NewTemplateData()
data.SetVariable("productName", "WordZero处理器")
data.SetVariable("price", 299.99)
data.SetVariable("quantity", 100)
data.SetVariable("inStock", true)
data.SetVariable("description", "高效的Word文档处理工具")
data.SetVariable("updateTime", "2024-12-01 15:30:00")
// 渲染并保存文档
resultDoc, err := engine.RenderTemplateToDocument("product_info", data)
if err != nil {
t.Fatalf("Failed to render template: %v", err)
}
filename := "output/test_variable_replacement_integration.docx"
err = resultDoc.Save(filename)
if err != nil {
t.Fatalf("Failed to save document: %v", err)
}
// 验证文档内容
if len(resultDoc.Body.Elements) == 0 {
t.Error("Expected document to have content")
}
t.Logf("Variable replacement test completed: %s", filename)
}
// testConditionalStatementsIntegration 测试条件语句集成功能
func testConditionalStatementsIntegration(t *testing.T) {
// 创建基础文档
doc := document.New()
// 添加包含条件语句的段落
doc.AddParagraph("用户权限报告")
doc.AddParagraph("")
doc.AddParagraph("用户名:{{username}}")
doc.AddParagraph("")
doc.AddParagraph("{{#if isAdmin}}管理员权限:")
doc.AddParagraph("- 系统配置访问权限")
doc.AddParagraph("- 用户管理权限")
doc.AddParagraph("- 数据备份权限{{/if}}")
doc.AddParagraph("{{#if isEditor}}编辑权限:")
doc.AddParagraph("- 内容编辑权限")
doc.AddParagraph("- 文档管理权限{{/if}}")
doc.AddParagraph("{{#if isViewer}}查看权限:")
doc.AddParagraph("- 只读访问权限{{/if}}")
engine := document.NewTemplateEngine()
_, err := engine.LoadTemplateFromDocument("user_permissions", doc)
if err != nil {
t.Fatalf("Failed to load template from document: %v", err)
}
// 测试不同权限组合
testCases := []struct {
name string
username string
isAdmin bool
isEditor bool
isViewer bool
expectedFile string
}{
{
name: "管理员权限",
username: "admin_user",
isAdmin: true,
isEditor: false,
isViewer: false,
expectedFile: "test_conditional_admin.docx",
},
{
name: "编辑员权限",
username: "editor_user",
isAdmin: false,
isEditor: true,
isViewer: false,
expectedFile: "test_conditional_editor.docx",
},
{
name: "查看者权限",
username: "viewer_user",
isAdmin: false,
isEditor: false,
isViewer: true,
expectedFile: "test_conditional_viewer.docx",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
data := document.NewTemplateData()
data.SetVariable("username", tc.username)
data.SetCondition("isAdmin", tc.isAdmin)
data.SetCondition("isEditor", tc.isEditor)
data.SetCondition("isViewer", tc.isViewer)
resultDoc, err := engine.RenderTemplateToDocument("user_permissions", data)
if err != nil {
t.Fatalf("Failed to render template for %s: %v", tc.name, err)
}
filename := "output/" + tc.expectedFile
err = resultDoc.Save(filename)
if err != nil {
t.Fatalf("Failed to save document for %s: %v", tc.name, err)
}
// 验证文档有内容
if len(resultDoc.Body.Elements) == 0 {
t.Errorf("Expected document for %s to have content", tc.name)
}
t.Logf("Conditional test for %s completed: %s", tc.name, filename)
})
}
}
// testLoopStatementsIntegration 测试循环语句集成功能
func testLoopStatementsIntegration(t *testing.T) {
// 创建基础文档
doc := document.New()
// 添加包含循环的表格
tableConfig := &document.TableConfig{
Rows: 4,
Cols: 3,
Data: [][]string{
{"序号", "商品名称", "价格"},
{"{{@index}}", "{{name}}", "{{price}} 元"},
{"", "", ""},
{"", "", ""},
},
}
doc.AddTable(tableConfig)
engine := document.NewTemplateEngine()
_, err := engine.LoadTemplateFromDocument("inventory_report", doc)
if err != nil {
t.Fatalf("Failed to load template from document: %v", err)
}
// 准备数据
data := document.NewTemplateData()
data.SetVariable("reportDate", "2024-12-01")
products := []interface{}{
map[string]interface{}{"name": "笔记本电脑", "price": "8999"},
map[string]interface{}{"name": "无线鼠标", "price": "199"},
map[string]interface{}{"name": "机械键盘", "price": "599"},
}
data.SetList("products", products)
// 渲染模板
resultDoc, err := engine.RenderTemplateToDocument("inventory_report", data)
if err != nil {
t.Fatalf("Failed to render template: %v", err)
}
filename := "output/test_loop_statements_integration.docx"
err = resultDoc.Save(filename)
if err != nil {
t.Fatalf("Failed to save document: %v", err)
}
// 验证文档内容
if len(resultDoc.Body.Elements) == 0 {
t.Error("Expected document to have content")
}
t.Logf("Loop statement test completed: %s", filename)
}
// testStructDataBindingIntegration 测试结构体绑定集成功能
func testStructDataBindingIntegration(t *testing.T) {
type Address struct {
Street string
City string
Province string
PostCode string
}
type Contact struct {
Phone string
Email string
Fax string
}
type Employee struct {
ID int
Name string
Position string
Department string
Salary float64
IsManager bool
HireDate string
Address Address
Contact Contact
}
// 创建基础文档
doc := document.New()
// 添加员工信息模板
doc.AddParagraph("员工详细信息")
doc.AddParagraph("")
doc.AddParagraph("员工编号: {{ID}}")
doc.AddParagraph("姓名: {{Name}}")
doc.AddParagraph("职位: {{Position}}")
doc.AddParagraph("部门: {{Department}}")
doc.AddParagraph("薪资: {{Salary}} 元")
doc.AddParagraph("是否管理者: {{IsManager}}")
doc.AddParagraph("入职日期: {{HireDate}}")
doc.AddParagraph("")
doc.AddParagraph("联系信息:")
doc.AddParagraph("电话: {{Phone}}")
doc.AddParagraph("邮箱: {{Email}}")
doc.AddParagraph("传真: {{Fax}}")
doc.AddParagraph("")
doc.AddParagraph("地址信息:")
doc.AddParagraph("街道: {{Street}}")
doc.AddParagraph("城市: {{City}}")
doc.AddParagraph("省份: {{Province}}")
doc.AddParagraph("邮编: {{PostCode}}")
engine := document.NewTemplateEngine()
_, err := engine.LoadTemplateFromDocument("employee_detail", doc)
if err != nil {
t.Fatalf("Failed to load template from document: %v", err)
}
// 创建员工数据
employee := Employee{
ID: 1001,
Name: "张三",
Position: "软件工程师",
Department: "技术部",
Salary: 15000.00,
IsManager: false,
HireDate: "2023-06-15",
Address: Address{
Street: "科技大道123号",
City: "深圳",
Province: "广东",
PostCode: "518000",
},
Contact: Contact{
Phone: "13800138000",
Email: "zhangsan@example.com",
Fax: "0755-88888888",
},
}
// 使用结构体绑定数据
data := document.NewTemplateData()
err = data.FromStruct(employee)
if err != nil {
t.Fatalf("Failed to bind struct data: %v", err)
}
// 渲染模板
resultDoc, err := engine.RenderTemplateToDocument("employee_detail", data)
if err != nil {
t.Fatalf("Failed to render template: %v", err)
}
filename := "output/test_struct_data_binding_integration.docx"
err = resultDoc.Save(filename)
if err != nil {
t.Fatalf("Failed to save document: %v", err)
}
// 验证文档内容
if len(resultDoc.Body.Elements) == 0 {
t.Error("Expected employee detail document to have content")
}
t.Logf("Struct data binding test completed: %s", filename)
}
// cleanupTestFiles 清理测试文件
func cleanupTestFiles() {
files := []string{
"output/test_variable_replacement_integration.docx",
"output/test_conditional_admin.docx",
"output/test_conditional_editor.docx",
"output/test_conditional_viewer.docx",
"output/test_loop_statements_integration.docx",
"output/test_struct_data_binding_integration.docx",
}
for _, file := range files {
if _, err := os.Stat(file); err == nil {
os.Remove(file)
}
}
}