143 lines
4.5 KiB
C#
143 lines
4.5 KiB
C#
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 分页查询,每页返回的数据量应不超过 pageSize(50),且所有页的数据合并后应等于总记录数。
|
||
/// 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
|
||
}
|
||
}
|