WorkCamera/client/WorkCameraExport.Tests/ExportServicePropertyTests.cs
2026-01-10 14:45:55 +08:00

143 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FsCheck;
using FsCheck.Xunit;
using OfficeOpenXml;
using WorkCameraExport.Models;
using WorkCameraExport.Services;
using Xunit;
namespace WorkCameraExport.Tests
{
/// <summary>
/// ExportService 属性测试
/// Feature: work-camera-2.0.1
/// </summary>
public class ExportServicePropertyTests : IDisposable
{
private readonly string _testOutputDir;
public ExportServicePropertyTests()
{
_testOutputDir = Path.Combine(Path.GetTempPath(), $"ExportService_Test_{Guid.NewGuid():N}");
Directory.CreateDirectory(_testOutputDir);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
}
public void Dispose()
{
try
{
if (Directory.Exists(_testOutputDir))
{
Directory.Delete(_testOutputDir, true);
}
}
catch
{
// 忽略清理错误
}
}
#region Property 6:
/// <summary>
/// Property 6: 分页数据获取
/// For any 分页查询,每页返回的数据量应不超过 pageSize50且所有页的数据合并后应等于总记录数。
/// Validates: Requirements 6.3
/// </summary>
[Property(MaxTest = 100)]
public Property PaginatedData_PageSize_ShouldNotExceedLimit()
{
return Prop.ForAll(
Arb.From<PositiveInt>(),
Arb.From<PositiveInt>(),
(totalCountGen, pageSizeGen) =>
{
var totalCount = (totalCountGen.Get % 200) + 1; // 1-200 条记录
var pageSize = (pageSizeGen.Get % 50) + 1; // 1-50 每页
// 模拟分页
var pages = SimulatePagination(totalCount, pageSize);
// 验证每页数据量不超过 pageSize
var allPagesValid = pages.All(p => p.Count <= pageSize);
// 验证总数据量等于 totalCount
var totalFromPages = pages.Sum(p => p.Count);
return (allPagesValid && totalFromPages == totalCount)
.Label($"All pages should have <= {pageSize} items and total should be {totalCount}, got {totalFromPages}");
});
}
/// <summary>
/// Property 6 扩展: 分页后的数据应保持顺序
/// </summary>
[Property(MaxTest = 100)]
public Property PaginatedData_Order_ShouldBePreserved()
{
return Prop.ForAll(
Arb.From<PositiveInt>(),
(totalCountGen) =>
{
var totalCount = (totalCountGen.Get % 100) + 1;
var pageSize = 50;
// 生成有序数据
var allData = Enumerable.Range(1, totalCount).ToList();
// 模拟分页获取
var pages = SimulatePaginationWithData(allData, pageSize);
// 合并所有页
var merged = pages.SelectMany(p => p).ToList();
// 验证顺序
var orderPreserved = merged.SequenceEqual(allData);
return orderPreserved.Label("Data order should be preserved after pagination");
});
}
#endregion
#region
/// <summary>
/// 模拟分页
/// </summary>
private List<List<int>> SimulatePagination(int totalCount, int pageSize)
{
var pages = new List<List<int>>();
var remaining = totalCount;
var pageNum = 0;
while (remaining > 0)
{
var count = Math.Min(remaining, pageSize);
pages.Add(Enumerable.Range(pageNum * pageSize + 1, count).ToList());
remaining -= count;
pageNum++;
}
return pages;
}
/// <summary>
/// 模拟分页(带数据)
/// </summary>
private List<List<int>> SimulatePaginationWithData(List<int> data, int pageSize)
{
var pages = new List<List<int>>();
for (int i = 0; i < data.Count; i += pageSize)
{
pages.Add(data.Skip(i).Take(pageSize).ToList());
}
return pages;
}
#endregion
}
}