using AvParser.Core.Collecting; using AvParser.Infrastructure.Storage; using AvParser.UI.Media; using Microsoft.Extensions.Logging.Abstractions; namespace AvParser.UI.Tests; /// /// The cache's refusals. /// /// /// Only the paths that answer before touching a decoder are covered here: decoding needs an /// Avalonia rendering platform, which this project deliberately does not start. The decode itself /// is one framework call; what is worth pinning is that the cache never reaches it for content it /// cannot handle, because doing so would mean an exception per tile. /// public sealed class ThumbnailCacheTests : IDisposable { private readonly string _root = Path.Combine(Path.GetTempPath(), "AvParserTests", Guid.NewGuid().ToString("N")); private readonly ThumbnailCache _cache; public ThumbnailCacheTests() { var paths = new AppPaths(_root); paths.EnsureCreated(); _cache = new ThumbnailCache(paths, NullLogger.Instance); } public void Dispose() { _cache.Dispose(); if (Directory.Exists(_root)) { Directory.Delete(_root, recursive: true); } } [Theory] [InlineData(MediaKind.Mp4)] [InlineData(MediaKind.WebM)] public async Task A_video_is_refused_without_looking_at_the_disk(MediaKind kind) { var result = await _cache.GetAsync( new string('a', 64), ".mp4", kind, 220, TestContext.Current.CancellationToken ); result.ShouldBeNull(); } [Fact] public async Task A_missing_blob_is_a_blank_tile_rather_than_a_throw() { var result = await _cache.GetAsync( new string('b', 64), ".png", MediaKind.Png, 220, TestContext.Current.CancellationToken ); result.ShouldBeNull(); } [Fact] public void Clearing_an_empty_cache_is_harmless() => _cache.Clear(); [Fact] public void The_capacity_leaves_room_for_more_than_one_screenful() { // The cache disposes what it evicts, so a capacity near the page size would dispose // bitmaps that are still on screen. ThumbnailCache.Capacity.ShouldBeGreaterThan(120 * 2); } }