mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-27 21:58:05 +08:00
176 lines
5.6 KiB
C#
176 lines
5.6 KiB
C#
using System.Runtime.CompilerServices;
|
|
using Avalonia.Platform.Storage;
|
|
|
|
namespace AtomUI.Desktop.Controls.Tests.Upload;
|
|
|
|
internal abstract class TestStorageItem : IStorageItem
|
|
{
|
|
public string Name { get; }
|
|
public Uri Path { get; }
|
|
public int DisposeCount { get; private set; }
|
|
public bool CanBookmark => false;
|
|
|
|
protected TestStorageItem(string name, string path)
|
|
{
|
|
Name = name;
|
|
Path = new Uri(path, UriKind.Absolute);
|
|
}
|
|
|
|
public virtual Task<StorageItemProperties> GetBasicPropertiesAsync()
|
|
{
|
|
return Task.FromResult(new StorageItemProperties());
|
|
}
|
|
|
|
public Task<string?> SaveBookmarkAsync() => Task.FromResult<string?>(null);
|
|
|
|
public Task<IStorageFolder?> GetParentAsync() => Task.FromResult<IStorageFolder?>(null);
|
|
|
|
public Task DeleteAsync() => Task.CompletedTask;
|
|
|
|
public Task<IStorageItem?> MoveAsync(IStorageFolder destination) => Task.FromResult<IStorageItem?>(null);
|
|
|
|
public void Dispose()
|
|
{
|
|
DisposeCount++;
|
|
}
|
|
}
|
|
|
|
internal sealed class TestStorageFile : TestStorageItem, IStorageFile
|
|
{
|
|
private readonly byte[] _content;
|
|
private readonly StorageItemProperties _properties;
|
|
|
|
public int OpenReadCount { get; private set; }
|
|
public Exception? MetadataException { get; init; }
|
|
public Exception? OpenReadException { get; init; }
|
|
|
|
public TestStorageFile(
|
|
string name,
|
|
string path,
|
|
byte[]? content = null,
|
|
ulong? size = null,
|
|
DateTimeOffset? dateCreated = null,
|
|
DateTimeOffset? dateModified = null)
|
|
: base(name, path)
|
|
{
|
|
_content = content ?? [1, 2, 3];
|
|
_properties = new StorageItemProperties(size ?? (ulong)_content.Length, dateCreated, dateModified);
|
|
}
|
|
|
|
public override Task<StorageItemProperties> GetBasicPropertiesAsync()
|
|
{
|
|
return MetadataException is null
|
|
? Task.FromResult(_properties)
|
|
: Task.FromException<StorageItemProperties>(MetadataException);
|
|
}
|
|
|
|
public Task<Stream> OpenReadAsync()
|
|
{
|
|
OpenReadCount++;
|
|
return OpenReadException is null
|
|
? Task.FromResult<Stream>(new MemoryStream(_content, writable: false))
|
|
: Task.FromException<Stream>(OpenReadException);
|
|
}
|
|
|
|
public Task<Stream> OpenWriteAsync()
|
|
{
|
|
return Task.FromResult<Stream>(new MemoryStream());
|
|
}
|
|
}
|
|
|
|
internal sealed class ThrowingStorageFile : IStorageFile
|
|
{
|
|
public string Name { get; }
|
|
public Uri Path { get; }
|
|
public bool CanBookmark => false;
|
|
public int DisposeCount { get; private set; }
|
|
|
|
internal ThrowingStorageFile(string name, string path)
|
|
{
|
|
Name = name;
|
|
Path = new Uri(path, UriKind.Absolute);
|
|
}
|
|
|
|
public Task<StorageItemProperties> GetBasicPropertiesAsync() =>
|
|
Task.FromResult(new StorageItemProperties(3));
|
|
|
|
public Task<Stream> OpenReadAsync() =>
|
|
Task.FromResult<Stream>(new MemoryStream([1, 2, 3], writable: false));
|
|
|
|
public Task<Stream> OpenWriteAsync() =>
|
|
Task.FromResult<Stream>(new MemoryStream());
|
|
|
|
public Task<string?> SaveBookmarkAsync() => Task.FromResult<string?>(null);
|
|
|
|
public Task<IStorageFolder?> GetParentAsync() => Task.FromResult<IStorageFolder?>(null);
|
|
|
|
public Task DeleteAsync() => Task.CompletedTask;
|
|
|
|
public Task<IStorageItem?> MoveAsync(IStorageFolder destination) =>
|
|
Task.FromResult<IStorageItem?>(null);
|
|
|
|
public void Dispose()
|
|
{
|
|
DisposeCount++;
|
|
throw new InvalidOperationException($"Dispose failed for {Name}.");
|
|
}
|
|
}
|
|
|
|
internal sealed class TestStorageFolder : TestStorageItem, IStorageFolder
|
|
{
|
|
private readonly IReadOnlyList<IStorageItem> _items;
|
|
|
|
public Exception? EnumerationException { get; init; }
|
|
public TaskCompletionSource<bool>? EnumerationGate { get; init; }
|
|
public TaskCompletionSource EnumerationStarted { get; } =
|
|
new(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
public int? PauseAfterItemCount { get; init; }
|
|
public TaskCompletionSource<bool>? EnumerationPauseGate { get; init; }
|
|
public TaskCompletionSource EnumerationPaused { get; } =
|
|
new(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
|
|
public TestStorageFolder(string name, string path, params IStorageItem[] items)
|
|
: base(name, path)
|
|
{
|
|
_items = items;
|
|
}
|
|
|
|
public IAsyncEnumerable<IStorageItem> GetItemsAsync() => EnumerateAsync();
|
|
|
|
public Task<IStorageFolder?> GetFolderAsync(string name) => Task.FromResult<IStorageFolder?>(null);
|
|
|
|
public Task<IStorageFile?> GetFileAsync(string name) => Task.FromResult<IStorageFile?>(null);
|
|
|
|
public Task<IStorageFile?> CreateFileAsync(string name) => Task.FromResult<IStorageFile?>(null);
|
|
|
|
public Task<IStorageFolder?> CreateFolderAsync(string name) => Task.FromResult<IStorageFolder?>(null);
|
|
|
|
private async IAsyncEnumerable<IStorageItem> EnumerateAsync(
|
|
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
|
{
|
|
EnumerationStarted.TrySetResult();
|
|
if (EnumerationGate is not null)
|
|
{
|
|
await EnumerationGate.Task.WaitAsync(cancellationToken);
|
|
}
|
|
|
|
if (EnumerationException is not null)
|
|
{
|
|
throw EnumerationException;
|
|
}
|
|
|
|
var yieldedCount = 0;
|
|
foreach (var item in _items)
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
yield return item;
|
|
yieldedCount++;
|
|
if (PauseAfterItemCount == yieldedCount && EnumerationPauseGate is not null)
|
|
{
|
|
EnumerationPaused.TrySetResult();
|
|
await EnumerationPauseGate.Task.WaitAsync(cancellationToken);
|
|
}
|
|
}
|
|
}
|
|
}
|