using Microsoft.VisualStudio.TestTools.UnitTesting; using OwlCore.Events; using StrixMusic.Sdk.MediaPlayback; using StrixMusic.Sdk.Plugins.Model; using System; using System.Collections.Generic; using System.Reflection; using System.Threading; using System.Threading.Tasks; using StrixMusic.Sdk.AdapterModels; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.BaseModels; using StrixMusic.Sdk.CoreModels; namespace StrixMusic.Sdk.Tests.Plugins.Models { [TestClass] public class SearchHistoryPluginBaseTests { private static bool NoInner(MemberInfo x) => !x.Name.Contains("Inner"); private static bool NoInnerOrSources(MemberInfo x) => NoInner(x) && !x.Name.ToLower().Contains("sources"); [Flags] public enum PossiblePlugins { None = 0, Playable = 1, Downloadable = 2, ArtistCollection = 4, AlbumCollection = 8, TrackCollection = 16, PlaylistCollection = 32, ImageCollection = 64, UrlCollection = 128, } [TestMethod, Timeout(1000)] public void NoPlugins() { var builder = new SdkModelPlugin(SdkTestPluginMetadata.Metadata).SearchHistory; var finalTestClass = new Unimplemented(); var emptyChain = builder.Execute(finalTestClass); Assert.AreSame(emptyChain, finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(emptyChain); } [TestMethod, Timeout(1000)] public void PluginNoOverride() { // No plugins. var builder = new SdkModelPlugin(SdkTestPluginMetadata.Metadata).SearchHistory; var finalTestClass = new Unimplemented(); var emptyChain = builder.Execute(finalTestClass); Assert.AreSame(emptyChain, finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(emptyChain); // No overrides. builder.Add(x => new NoOverride(x)); var noOverride = builder.Execute(finalTestClass); Assert.AreNotSame(noOverride, emptyChain); Assert.AreNotSame(noOverride, finalTestClass); Helpers.AssertAllMembersThrowOnAccess, NoOverride>(noOverride, customFilter: NoInner); } [TestMethod, Timeout(25000)] public void PluginFullyCustom() { // No plugins. var builder = new SdkModelPlugin(SdkTestPluginMetadata.Metadata).SearchHistory; var finalTestClass = new Unimplemented(); var emptyChain = builder.Execute(finalTestClass); Assert.AreSame(emptyChain, finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(emptyChain); // No overrides. builder.Add(x => new NoOverride(x)); var noOverride = builder.Execute(finalTestClass); Assert.AreNotSame(noOverride, emptyChain); Assert.AreNotSame(noOverride, finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(noOverride, customFilter: NoInner); // Fully custom builder.Add(x => new FullyCustom(x)); var allCustom = builder.Execute(finalTestClass); Assert.AreNotSame(noOverride, emptyChain); Assert.AreNotSame(noOverride, finalTestClass); Helpers.AssertAllThrowsOnMemberAccess>(allCustom, customFilter: NoInnerOrSources); } [TestMethod, Timeout(5000)] [AllEnumFlagCombinations(typeof(PossiblePlugins))] public void PluginFullyCustomWith_AllCombinations(PossiblePlugins data) { var builder = new SdkModelPlugin(SdkTestPluginMetadata.Metadata).SearchHistory; var defaultImplementation = new Unimplemented(); builder.Add(x => new NoOverride(x) { InnerDownloadable = data.HasFlag(PossiblePlugins.Downloadable) ? new DownloadablePluginBaseTests.Unimplemented() : x, InnerPlayable = data.HasFlag(PossiblePlugins.Playable) ? new PlayablePluginBaseTests.Unimplemented() : x, InnerArtistCollection = data.HasFlag(PossiblePlugins.ArtistCollection) ? new ArtistCollectionPluginBaseTests.Unimplemented() : x, InnerAlbumCollection = data.HasFlag(PossiblePlugins.AlbumCollection) ? new AlbumCollectionPluginBaseTests.Unimplemented() : x, InnerTrackCollection = data.HasFlag(PossiblePlugins.TrackCollection) ? new TrackCollectionPluginBaseTests.Unimplemented() : x, InnerPlaylistCollection = data.HasFlag(PossiblePlugins.PlaylistCollection) ? new PlaylistCollectionPluginBaseTests.Unimplemented() : x, InnerImageCollection = data.HasFlag(PossiblePlugins.ImageCollection) ? new ImageCollectionPluginBaseTests.Unimplemented() : x, InnerUrlCollection = data.HasFlag(PossiblePlugins.UrlCollection) ? new UrlCollectionPluginBaseTests.Unimplemented() : x, } ); var finalImpl = builder.Execute(defaultImplementation); Assert.AreNotSame(finalImpl, defaultImplementation); Assert.IsInstanceOfType(finalImpl, typeof(NoOverride)); var expectedExceptionsWhenDisposing = new List { typeof(AccessedException), }; if (data.HasFlag(PossiblePlugins.Downloadable)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, DownloadablePluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: typeof(IAsyncDisposable) ); } if (data.HasFlag(PossiblePlugins.Playable)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, PlayablePluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: new[] { typeof(IAsyncDisposable), typeof(DownloadablePluginBaseTests.Unimplemented), typeof(ImageCollectionPluginBaseTests.Unimplemented), typeof(UrlCollectionPluginBaseTests.Unimplemented) } ); } if (data.HasFlag(PossiblePlugins.ArtistCollection)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, ArtistCollectionPluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: new[] { typeof(IAsyncDisposable), typeof(DownloadablePluginBaseTests.Unimplemented), typeof(ImageCollectionPluginBaseTests.Unimplemented), typeof(UrlCollectionPluginBaseTests.Unimplemented), typeof(PlayablePluginBaseTests.Unimplemented), typeof(IPlayableCollectionItem), } ); } if (data.HasFlag(PossiblePlugins.AlbumCollection)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, AlbumCollectionPluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: new[] { typeof(IAsyncDisposable), typeof(DownloadablePluginBaseTests.Unimplemented), typeof(ImageCollectionPluginBaseTests.Unimplemented), typeof(UrlCollectionPluginBaseTests.Unimplemented), typeof(PlayablePluginBaseTests.Unimplemented), typeof(IPlayableCollectionItem), } ); } if (data.HasFlag(PossiblePlugins.PlaylistCollection)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, PlaylistCollectionPluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: new[] { typeof(IAsyncDisposable), typeof(DownloadablePluginBaseTests.Unimplemented), typeof(ImageCollectionPluginBaseTests.Unimplemented), typeof(UrlCollectionPluginBaseTests.Unimplemented), typeof(PlayablePluginBaseTests.Unimplemented), typeof(IPlayableCollectionItem), } ); } if (data.HasFlag(PossiblePlugins.TrackCollection)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, TrackCollectionPluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: new[] { typeof(IAsyncDisposable), typeof(DownloadablePluginBaseTests.Unimplemented), typeof(ImageCollectionPluginBaseTests.Unimplemented), typeof(UrlCollectionPluginBaseTests.Unimplemented), typeof(PlayablePluginBaseTests.Unimplemented), typeof(IPlayableCollectionItem), } ); } if (data.HasFlag(PossiblePlugins.ImageCollection)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, ImageCollectionPluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: typeof(IAsyncDisposable) ); } if (data.HasFlag(PossiblePlugins.UrlCollection)) { expectedExceptionsWhenDisposing.Add(typeof(AccessedException)); Helpers.AssertAllMembersThrowOnAccess, UrlCollectionPluginBaseTests.Unimplemented>( finalImpl, customFilter: NoInnerOrSources, typesToExclude: typeof(IAsyncDisposable) ); } Helpers.AssertAllThrowsOnMemberAccess( finalImpl, customFilter: NoInnerOrSources, expectedExceptions: expectedExceptionsWhenDisposing.ToArray() ); } [TestMethod, Timeout(5000)] [AllEnumFlagCombinations(typeof(PossiblePlugins))] public async Task DisposeAsync_AllCombinations(PossiblePlugins data) { var builder = new SdkModelPlugin(SdkTestPluginMetadata.Metadata).SearchHistory; var defaultImplementation = new NotBlockingDisposeAsync(); builder.Add(x => new NoOverride(x) { InnerDownloadable = data.HasFlag(PossiblePlugins.Downloadable) ? new DownloadablePluginBaseTests.NotBlockingDisposeAsync() : x, InnerPlayable = data.HasFlag(PossiblePlugins.Playable) ? new PlayablePluginBaseTests.NotBlockingDisposeAsync() : x, InnerArtistCollection = data.HasFlag(PossiblePlugins.ArtistCollection) ? new ArtistCollectionPluginBaseTests.NotBlockingDisposeAsync() : x, InnerAlbumCollection = data.HasFlag(PossiblePlugins.AlbumCollection) ? new AlbumCollectionPluginBaseTests.NotBlockingDisposeAsync() : x, InnerTrackCollection = data.HasFlag(PossiblePlugins.TrackCollection) ? new TrackCollectionPluginBaseTests.NotBlockingDisposeAsync() : x, InnerPlaylistCollection = data.HasFlag(PossiblePlugins.PlaylistCollection) ? new PlaylistCollectionPluginBaseTests.NotBlockingDisposeAsync() : x, InnerImageCollection = data.HasFlag(PossiblePlugins.ImageCollection) ? new ImageCollectionPluginBaseTests.NotBlockingDisposeAsync() : x, InnerUrlCollection = data.HasFlag(PossiblePlugins.UrlCollection) ? new UrlCollectionPluginBaseTests.NotBlockingDisposeAsync() : x, }); var finalImpl = builder.Execute(defaultImplementation); Assert.AreNotSame(finalImpl, defaultImplementation); Assert.IsInstanceOfType(finalImpl, typeof(NoOverride)); await finalImpl.DisposeAsync(); } internal class FullyCustom : SearchHistoryPluginBase { public FullyCustom(ISearchHistory inner) : base(new ModelPluginMetadata("", nameof(FullyCustom), "", new Version()), inner) { } internal static AccessedException AccessedException { get; } = new(); public override ValueTask DisposeAsync() => throw AccessedException; public override Task IsAddImageAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemoveImageAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task RemoveImageAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override int TotalImageCount => throw AccessedException; public override event EventHandler? ImagesCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override int TotalUrlCount => throw AccessedException; public override Task RemoveUrlAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsAddUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemoveUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? UrlsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override string Id => throw AccessedException; public override string Name => throw AccessedException; public override string? Description => throw AccessedException; public override DateTime? LastPlayed => throw AccessedException; public override PlaybackState PlaybackState => throw AccessedException; public override TimeSpan Duration => throw AccessedException; public override bool IsChangeNameAsyncAvailable => throw AccessedException; public override bool IsChangeDescriptionAsyncAvailable => throw AccessedException; public override bool IsChangeDurationAsyncAvailable => throw AccessedException; public override Task ChangeNameAsync(string name, CancellationToken cancellationToken = default) => throw AccessedException; public override Task ChangeDescriptionAsync(string? description, CancellationToken cancellationToken = default) => throw AccessedException; public override Task ChangeDurationAsync(TimeSpan duration, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? PlaybackStateChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? NameChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? DescriptionChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? DurationChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? LastPlayedChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsChangeNameAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsChangeDescriptionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsChangeDurationAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override DateTime? AddedAt => throw AccessedException; public override int TotalPlaylistItemsCount => throw AccessedException; public override bool IsPlayPlaylistCollectionAsyncAvailable => throw AccessedException; public override bool IsPausePlaylistCollectionAsyncAvailable => throw AccessedException; public override Task PlayPlaylistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task PausePlaylistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task RemovePlaylistItemAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsAddPlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemovePlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? IsPlayPlaylistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsPausePlaylistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? PlaylistItemsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override int TotalTrackCount => throw AccessedException; public override bool IsPlayTrackCollectionAsyncAvailable => throw AccessedException; public override bool IsPauseTrackCollectionAsyncAvailable => throw AccessedException; public override Task PlayTrackCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task PauseTrackCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task RemoveTrackAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsAddTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemoveTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? IsPlayTrackCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsPauseTrackCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? TracksCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override int TotalAlbumItemsCount => throw AccessedException; public override bool IsPlayAlbumCollectionAsyncAvailable => throw AccessedException; public override bool IsPauseAlbumCollectionAsyncAvailable => throw AccessedException; public override Task PlayAlbumCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task PauseAlbumCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task RemoveAlbumItemAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsAddAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemoveAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? IsPlayAlbumCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsPauseAlbumCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? AlbumItemsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override int TotalArtistItemsCount => throw AccessedException; public override bool IsPlayArtistCollectionAsyncAvailable => throw AccessedException; public override bool IsPauseArtistCollectionAsyncAvailable => throw AccessedException; public override Task PlayArtistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task PauseArtistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task RemoveArtistItemAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsAddArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemoveArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? IsPlayArtistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? IsPauseArtistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public override event EventHandler? ArtistItemsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override Task PlayPlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override Task PausePlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => throw AccessedException; public override int TotalChildrenCount => throw AccessedException; public override Task RemoveChildAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsAddChildAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override Task IsRemoveChildAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? ChildrenCountChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICoreImageCollection? other) => throw AccessedException; public override IAsyncEnumerable GetImagesAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddImageAsync(IImage image, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? ImagesChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICoreUrlCollection? other) => throw AccessedException; public override IAsyncEnumerable GetUrlsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddUrlAsync(IUrl url, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? UrlsChanged { add => throw AccessedException; remove => throw AccessedException; } public override DownloadInfo DownloadInfo => throw AccessedException; public override Task StartDownloadOperationAsync(DownloadOperation operation, CancellationToken cancellationToken = default) => throw AccessedException; public override event EventHandler? DownloadInfoChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICorePlaylistCollectionItem? other) => throw AccessedException; public override bool Equals(ICorePlaylistCollection? other) => throw AccessedException; public override Task PlayPlaylistCollectionAsync(IPlaylistCollectionItem playlistItem, CancellationToken cancellationToken = default) => throw AccessedException; public override IAsyncEnumerable GetPlaylistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddPlaylistItemAsync(IPlaylistCollectionItem playlistItem, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? PlaylistItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICoreTrackCollection? other) => throw AccessedException; public override Task PlayTrackCollectionAsync(ITrack track, CancellationToken cancellationToken = default) => throw AccessedException; public override IAsyncEnumerable GetTracksAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddTrackAsync(ITrack track, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? TracksChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICoreAlbumCollectionItem? other) => throw AccessedException; public override bool Equals(ICoreAlbumCollection? other) => throw AccessedException; public override Task PlayAlbumCollectionAsync(IAlbumCollectionItem albumItem, CancellationToken cancellationToken = default) => throw AccessedException; public override IAsyncEnumerable GetAlbumItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddAlbumItemAsync(IAlbumCollectionItem album, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? AlbumItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICoreArtistCollectionItem? other) => throw AccessedException; public override bool Equals(ICoreArtistCollection? other) => throw AccessedException; public override Task PlayArtistCollectionAsync(IArtistCollectionItem artistItem, CancellationToken cancellationToken = default) => throw AccessedException; public override IAsyncEnumerable GetArtistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddArtistItemAsync(IArtistCollectionItem artistItem, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? ArtistItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICorePlayableCollectionGroupChildren? other) => throw AccessedException; public override Task PlayPlayableCollectionGroupAsync(IPlayableCollectionGroup collectionGroup, CancellationToken cancellationToken = default) => throw AccessedException; public override IAsyncEnumerable GetChildrenAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public override Task AddChildAsync(IPlayableCollectionGroup child, int index, CancellationToken cancellationToken = default) => throw AccessedException; public override event CollectionChangedEventHandler? ChildItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public override bool Equals(ICorePlayableCollectionGroup? other) => throw AccessedException; public override bool Equals(ICoreSearchHistory? other) => throw AccessedException; } internal class NoOverride : SearchHistoryPluginBase { public NoOverride(ISearchHistory inner) : base(new ModelPluginMetadata("", nameof(NoOverride), "", new Version()), inner) { } } internal class NotBlockingDisposeAsync : SearchHistoryPluginBase { public NotBlockingDisposeAsync() : base(new ModelPluginMetadata("", nameof(NotBlockingDisposeAsync), "", new Version()), new Unimplemented()) { } /// public override ValueTask DisposeAsync() => default; } internal class Unimplemented : ISearchHistory { internal static AccessedException AccessedException { get; } = new(); public event EventHandler? SourcesChanged { add => throw AccessedException; remove => throw AccessedException; } public ValueTask DisposeAsync() => throw AccessedException; public Task IsAddImageAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemoveImageAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task RemoveImageAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public int TotalImageCount => throw AccessedException; public event EventHandler? ImagesCountChanged { add => throw AccessedException; remove => throw AccessedException; } public int TotalUrlCount => throw AccessedException; public Task RemoveUrlAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsAddUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemoveUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? UrlsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public string Id => throw AccessedException; public string Name => throw AccessedException; public string? Description => throw AccessedException; public DateTime? LastPlayed => throw AccessedException; public PlaybackState PlaybackState => throw AccessedException; public TimeSpan Duration => throw AccessedException; public bool IsChangeNameAsyncAvailable => throw AccessedException; public bool IsChangeDescriptionAsyncAvailable => throw AccessedException; public bool IsChangeDurationAsyncAvailable => throw AccessedException; public Task ChangeNameAsync(string name, CancellationToken cancellationToken = default) => throw AccessedException; public Task ChangeDescriptionAsync(string? description, CancellationToken cancellationToken = default) => throw AccessedException; public Task ChangeDurationAsync(TimeSpan duration, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? PlaybackStateChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? NameChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? DescriptionChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? DurationChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? LastPlayedChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsChangeNameAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsChangeDescriptionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsChangeDurationAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public DateTime? AddedAt => throw AccessedException; public int TotalPlaylistItemsCount => throw AccessedException; public bool IsPlayPlaylistCollectionAsyncAvailable => throw AccessedException; public bool IsPausePlaylistCollectionAsyncAvailable => throw AccessedException; public Task PlayPlaylistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task PausePlaylistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task RemovePlaylistItemAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsAddPlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemovePlaylistItemAvailableAsync(int index, CancellationToken cancellationToken) => throw AccessedException; public event EventHandler? IsPlayPlaylistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsPausePlaylistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? PlaylistItemsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public int TotalTrackCount => throw AccessedException; public bool IsPlayTrackCollectionAsyncAvailable => throw AccessedException; public bool IsPauseTrackCollectionAsyncAvailable => throw AccessedException; public Task PlayTrackCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task PauseTrackCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task RemoveTrackAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsAddTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemoveTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? IsPlayTrackCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsPauseTrackCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? TracksCountChanged { add => throw AccessedException; remove => throw AccessedException; } public int TotalAlbumItemsCount => throw AccessedException; public bool IsPlayAlbumCollectionAsyncAvailable => throw AccessedException; public bool IsPauseAlbumCollectionAsyncAvailable => throw AccessedException; public Task PlayAlbumCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task PauseAlbumCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task RemoveAlbumItemAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsAddAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemoveAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? IsPlayAlbumCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsPauseAlbumCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? AlbumItemsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public int TotalArtistItemsCount => throw AccessedException; public bool IsPlayArtistCollectionAsyncAvailable => throw AccessedException; public bool IsPauseArtistCollectionAsyncAvailable => throw AccessedException; public Task PlayArtistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task PauseArtistCollectionAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task RemoveArtistItemAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsAddArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemoveArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? IsPlayArtistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? IsPauseArtistCollectionAsyncAvailableChanged { add => throw AccessedException; remove => throw AccessedException; } public event EventHandler? ArtistItemsCountChanged { add => throw AccessedException; remove => throw AccessedException; } public Task PlayPlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => throw AccessedException; public Task PausePlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => throw AccessedException; public int TotalChildrenCount => throw AccessedException; public Task RemoveChildAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsAddChildAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public Task IsRemoveChildAvailableAsync(int index, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? ChildrenCountChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICoreImageCollection? other) => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; IReadOnlyList IMerged.Sources => throw AccessedException; public IAsyncEnumerable GetImagesAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddImageAsync(IImage image, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? ImagesChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICoreUrlCollection? other) => throw AccessedException; public IAsyncEnumerable GetUrlsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddUrlAsync(IUrl url, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? UrlsChanged { add => throw AccessedException; remove => throw AccessedException; } public DownloadInfo DownloadInfo => throw AccessedException; public Task StartDownloadOperationAsync(DownloadOperation operation, CancellationToken cancellationToken = default) => throw AccessedException; public event EventHandler? DownloadInfoChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICorePlaylistCollectionItem? other) => throw AccessedException; public bool Equals(ICorePlaylistCollection? other) => throw AccessedException; public Task PlayPlaylistCollectionAsync(IPlaylistCollectionItem playlistItem, CancellationToken cancellationToken = default) => throw AccessedException; public IAsyncEnumerable GetPlaylistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddPlaylistItemAsync(IPlaylistCollectionItem playlistItem, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? PlaylistItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICoreTrackCollection? other) => throw AccessedException; public Task PlayTrackCollectionAsync(ITrack track, CancellationToken cancellationToken = default) => throw AccessedException; public IAsyncEnumerable GetTracksAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddTrackAsync(ITrack track, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? TracksChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICoreAlbumCollectionItem? other) => throw AccessedException; public bool Equals(ICoreAlbumCollection? other) => throw AccessedException; public Task PlayAlbumCollectionAsync(IAlbumCollectionItem albumItem, CancellationToken cancellationToken = default) => throw AccessedException; public IAsyncEnumerable GetAlbumItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddAlbumItemAsync(IAlbumCollectionItem album, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? AlbumItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICoreArtistCollectionItem? other) => throw AccessedException; public bool Equals(ICoreArtistCollection? other) => throw AccessedException; public Task PlayArtistCollectionAsync(IArtistCollectionItem artistItem, CancellationToken cancellationToken = default) => throw AccessedException; public IAsyncEnumerable GetArtistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddArtistItemAsync(IArtistCollectionItem artistItem, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? ArtistItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICorePlayableCollectionGroupChildren? other) => throw AccessedException; public Task PlayPlayableCollectionGroupAsync(IPlayableCollectionGroup collectionGroup, CancellationToken cancellationToken = default) => throw AccessedException; public IAsyncEnumerable GetChildrenAsync(int limit, int offset, CancellationToken cancellationToken = default) => throw AccessedException; public Task AddChildAsync(IPlayableCollectionGroup child, int index, CancellationToken cancellationToken = default) => throw AccessedException; public event CollectionChangedEventHandler? ChildItemsChanged { add => throw AccessedException; remove => throw AccessedException; } public bool Equals(ICorePlayableCollectionGroup? other) => throw AccessedException; public IReadOnlyList Sources => throw AccessedException; public bool Equals(ICoreSearchHistory? other) => throw AccessedException; } } }