- PdfSharpCore 1.3.64 引入(纯托管,Unity IL2CPP 兼容,+9 DLL) - ReportData 结构化模型 + MarkdownRenderer + StandardPdfTemplate - IReportService.ExportReport(id, format) 按需导出 PDF/MD - 仿真后自动生成 MD 到 reports 目录,PDF 按需调用 - CJK 字体嵌入(SimHei),IPathProvider + GetFontPath - ReportGenerator 重构为构建 ReportData,去掉 emoji - check_unity_build.ps1 修复 -quit 参数缺失导致超时 - 对接文档 V2.0:坐标系/3D 可视化/完整枚举/Manager 签名/模型字段 - 262 测试全部通过
122 lines
4.5 KiB
C#
122 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using CounterDrone.Core;
|
|
using CounterDrone.Core.Reporting;
|
|
using Xunit;
|
|
|
|
namespace CounterDrone.Core.Tests
|
|
{
|
|
public class StandardPdfTemplateTests : IDisposable
|
|
{
|
|
private readonly string _testDir;
|
|
|
|
public StandardPdfTemplateTests()
|
|
{
|
|
_testDir = Path.Combine(Path.GetTempPath(), $"cd_pdf_{Guid.NewGuid():N}");
|
|
var paths = new TestPathProvider(_testDir);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(_testDir)) Directory.Delete(_testDir, true);
|
|
}
|
|
|
|
private static ReportData CreateSampleReport()
|
|
{
|
|
return new ReportData
|
|
{
|
|
Title = "仿真评估报告",
|
|
Header = new List<MetaItem>
|
|
{
|
|
new() { Label = "任务名称", Value = "城市防御测试" },
|
|
new() { Label = "任务编号", Value = "SIM-001" },
|
|
new() { Label = "仿真耗时", Value = "45.0 秒" },
|
|
},
|
|
Sections = new List<ReportSection>
|
|
{
|
|
new()
|
|
{
|
|
Title = "一、仿真结果",
|
|
Blocks = new List<ReportBlock>
|
|
{
|
|
new KeyValueBlock
|
|
{
|
|
LabelHeader = "统计项",
|
|
Items = new List<MetaItem>
|
|
{
|
|
new() { Label = "无人机总数", Value = "3" },
|
|
new() { Label = "被摧毁", Value = "3" },
|
|
new() { Label = "弹药发射", Value = "6" },
|
|
},
|
|
},
|
|
new TextBlock { Text = "对抗结果:✅ 成功拦截", Bold = true },
|
|
},
|
|
},
|
|
new()
|
|
{
|
|
Title = "六、事件时序",
|
|
Blocks = new List<ReportBlock>
|
|
{
|
|
new TableBlock
|
|
{
|
|
Headers = new[] { "时间(s)", "事件", "详情", "火力单元" },
|
|
Rows = new List<string[]>
|
|
{
|
|
new[] { "1.50", "🚀 弹药发射", "第 1 发 · 发射", "#1" },
|
|
new[] { "5.00", "☁️ 云团生成", "云团 #1 · 生成", "-" },
|
|
new[] { "8.30", "💥 目标击毁", "目标被摧毁", "-" },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
[Fact]
|
|
public void Render_ReturnsValidPdf()
|
|
{
|
|
var paths = new TestPathProvider(_testDir);
|
|
var template = new StandardPdfTemplate(paths.GetFontPath(), "CJK");
|
|
var pdf = template.Render(CreateSampleReport());
|
|
|
|
Assert.NotEmpty(pdf);
|
|
// PDF 文件头:%PDF
|
|
Assert.Equal(0x25, pdf[0]); // %
|
|
Assert.Equal(0x50, pdf[1]); // P
|
|
Assert.Equal(0x44, pdf[2]); // D
|
|
Assert.Equal(0x46, pdf[3]); // F
|
|
}
|
|
|
|
[Fact]
|
|
public void Render_MultiplePages_HandlesLongContent()
|
|
{
|
|
var data = CreateSampleReport();
|
|
// 添加大量事件行以触发分页
|
|
var eventRows = new List<string[]>();
|
|
for (int i = 0; i < 200; i++)
|
|
eventRows.Add(new[] { $"{i * 0.1:F1}", "🚀 弹药发射", $"第 {i + 1} 发 · 测试事件 {i}", $"#{(i % 3) + 1}" });
|
|
data.Sections.Add(new ReportSection
|
|
{
|
|
Title = "大量事件",
|
|
Blocks = new List<ReportBlock>
|
|
{
|
|
new TableBlock
|
|
{
|
|
Headers = new[] { "时间(s)", "事件", "详情", "单元" },
|
|
Rows = eventRows,
|
|
},
|
|
},
|
|
});
|
|
|
|
var paths = new TestPathProvider(_testDir);
|
|
var template = new StandardPdfTemplate(paths.GetFontPath(), "CJK");
|
|
var pdf = template.Render(data);
|
|
|
|
Assert.NotEmpty(pdf);
|
|
Assert.True(pdf.Length > 10000, $"PDF 应有多个页面,大小 {pdf.Length} bytes");
|
|
}
|
|
}
|
|
}
|