using FsCheck;
using FsCheck.Xunit;
using WorkCameraExport.Forms;
using Xunit;
namespace WorkCameraExport.Tests
{
///
/// 图片显示数量属性测试
/// Feature: work-camera-2.0.1, Property 1: 图片显示数量限制
/// Validates: Requirements 3.1, 3.2
///
public class ImageDisplayPropertyTests
{
private const int MaxThumbnailsToShow = 3;
///
/// Property 1: 图片显示数量限制
/// For any 工作记录,如果图片数量大于 3,则列表中显示的缩略图数量应等于 3,
/// 且徽章显示的数字应等于总图片数减 3。
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_WhenMoreThanThree_ShouldShowThreeWithBadge()
{
return Prop.ForAll(
Gen.Choose(4, 100).ToArbitrary(), // 4-100 张图片
(totalImages) =>
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
var displayCountCorrect = displayCount == MaxThumbnailsToShow;
var badgeCountCorrect = badgeCount == totalImages - MaxThumbnailsToShow;
return (displayCountCorrect && badgeCountCorrect)
.Label($"For {totalImages} images: displayCount={displayCount} (expected {MaxThumbnailsToShow}), " +
$"badgeCount={badgeCount} (expected {totalImages - MaxThumbnailsToShow})");
});
}
///
/// Property 1 扩展: 图片数量小于等于 3 时,显示全部图片,无徽章
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_WhenThreeOrLess_ShouldShowAllWithoutBadge()
{
return Prop.ForAll(
Gen.Choose(1, 3).ToArbitrary(), // 1-3 张图片
(totalImages) =>
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
var displayCountCorrect = displayCount == totalImages;
var badgeCountCorrect = badgeCount == 0;
return (displayCountCorrect && badgeCountCorrect)
.Label($"For {totalImages} images: displayCount={displayCount} (expected {totalImages}), " +
$"badgeCount={badgeCount} (expected 0)");
});
}
///
/// Property 1 扩展: 无图片时,显示数量和徽章数量都为 0
///
[Fact]
public void ImageDisplayCount_WhenZero_ShouldReturnZeros()
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(0);
Assert.Equal(0, displayCount);
Assert.Equal(0, badgeCount);
}
///
/// Property 1 扩展: 负数图片数量应返回 0
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_WhenNegative_ShouldReturnZeros()
{
return Prop.ForAll(
Gen.Choose(-100, -1).ToArbitrary(), // 负数
(totalImages) =>
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
return (displayCount == 0 && badgeCount == 0)
.Label($"For {totalImages} images: displayCount={displayCount}, badgeCount={badgeCount} (both should be 0)");
});
}
///
/// Property 1 扩展: 显示数量 + 徽章数量 应等于总图片数(当总数 > 0 时)
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_DisplayPlusBadge_ShouldEqualTotal()
{
return Prop.ForAll(
Gen.Choose(1, 1000).ToArbitrary(), // 1-1000 张图片
(totalImages) =>
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
// 当图片数 <= 3 时,displayCount = totalImages, badgeCount = 0
// 当图片数 > 3 时,displayCount = 3, badgeCount = totalImages - 3
// 两种情况下,displayCount + badgeCount 都应该等于 totalImages
var sum = displayCount + badgeCount;
return (sum == totalImages)
.Label($"For {totalImages} images: displayCount({displayCount}) + badgeCount({badgeCount}) = {sum} (expected {totalImages})");
});
}
///
/// Property 1 扩展: 显示数量应始终在 [0, 3] 范围内
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_DisplayCount_ShouldBeInValidRange()
{
return Prop.ForAll(
Arb.From(),
(totalImages) =>
{
var (displayCount, _) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
return (displayCount >= 0 && displayCount <= MaxThumbnailsToShow)
.Label($"For {totalImages} images: displayCount={displayCount} should be in [0, {MaxThumbnailsToShow}]");
});
}
///
/// Property 1 扩展: 徽章数量应始终 >= 0
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_BadgeCount_ShouldBeNonNegative()
{
return Prop.ForAll(
Arb.From(),
(totalImages) =>
{
var (_, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
return (badgeCount >= 0)
.Label($"For {totalImages} images: badgeCount={badgeCount} should be >= 0");
});
}
///
/// Property 1 扩展: 边界值测试 - 恰好 3 张图片
///
[Fact]
public void ImageDisplayCount_ExactlyThree_ShouldShowAllWithoutBadge()
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(3);
Assert.Equal(3, displayCount);
Assert.Equal(0, badgeCount);
}
///
/// Property 1 扩展: 边界值测试 - 恰好 4 张图片
///
[Fact]
public void ImageDisplayCount_ExactlyFour_ShouldShowThreeWithBadgeOne()
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(4);
Assert.Equal(3, displayCount);
Assert.Equal(1, badgeCount);
}
///
/// Property 1 扩展: 大量图片测试
///
[Property(MaxTest = 100)]
public Property ImageDisplayCount_LargeNumbers_ShouldHandleCorrectly()
{
return Prop.ForAll(
Gen.Choose(1000, 100000).ToArbitrary(), // 大量图片
(totalImages) =>
{
var (displayCount, badgeCount) = WorkRecordForm.CalculateImageDisplayInfo(totalImages);
var displayCountCorrect = displayCount == MaxThumbnailsToShow;
var badgeCountCorrect = badgeCount == totalImages - MaxThumbnailsToShow;
var sumCorrect = displayCount + badgeCount == totalImages;
return (displayCountCorrect && badgeCountCorrect && sumCorrect)
.Label($"For {totalImages} images: displayCount={displayCount}, badgeCount={badgeCount}");
});
}
}
}