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}"); }); } } }