1
0
Files
common/test/AMWD.Common.Tests/Utilities/AsyncQueueTest.cs
2025-11-13 20:30:44 +01:00

349 lines
8.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
namespace AMWD.Common.Tests.Utilities
{
[TestClass]
public class AsyncQueueTest
{
public TestContext TestContext { get; set; }
private Queue<TestElement> _internalQueue;
private TestElement _queueElement1;
private TestElement _queueElement2;
private TestElement _queueElement3;
[TestInitialize]
public void InitializeTest()
{
_queueElement1 = new TestElement
{
Number = 111,
Text = "one"
};
_queueElement2 = new TestElement
{
Number = 222,
Text = "two"
};
_queueElement3 = new TestElement
{
Number = 333,
Text = "three"
};
_internalQueue = new Queue<TestElement>();
_internalQueue.Enqueue(_queueElement1);
_internalQueue.Enqueue(_queueElement2);
_internalQueue.Enqueue(_queueElement3);
}
[TestMethod]
public void ShouldEnqueueItem()
{
// arrange
var element = new TestElement { Number = 1, Text = "Hello" };
_internalQueue.Clear();
var queue = GetQueue();
// act
queue.Enqueue(element);
// assert
Assert.HasCount(1, _internalQueue);
Assert.AreEqual(_internalQueue.Count, queue.Count);
}
[TestMethod]
public void ShouldEnqueueItemAndResetAvailableToken()
{
// arrange
var element = new TestElement { Number = 1, Text = "Hello" };
bool available = false;
_internalQueue.Clear();
var queue = GetQueue();
// act
var task = Task.Run(async () =>
{
await queue.WaitAsync(TestContext.CancellationToken);
available = true;
}, TestContext.CancellationToken);
queue.Enqueue(element);
task.Wait(TestContext.CancellationToken);
// assert
Assert.IsTrue(available);
}
[TestMethod]
public void ShouldEnqueueItemAndResetDequeueToken()
{
// arrange
var element = new TestElement { Number = 1, Text = "Hello" };
TestElement callback = null;
_internalQueue.Clear();
var queue = GetQueue();
// act
var task = Task.Run(async () =>
{
callback = await queue.DequeueAsync(TestContext.CancellationToken);
}, TestContext.CancellationToken);
queue.Enqueue(element);
task.Wait(TestContext.CancellationToken);
// assert
Assert.IsNotNull(callback);
Assert.AreEqual(element, callback);
}
[TestMethod]
public void ShouldEnqueueMultipleItems()
{
// arrange
var elements = new TestElement[]
{
new() { Number = 1, Text = "Hello" },
new() { Number = 2, Text = "World" },
};
_internalQueue.Clear();
var queue = GetQueue();
// act
queue.Enqueue(elements);
// assert
Assert.HasCount(2, _internalQueue);
Assert.HasCount(queue.Count, _internalQueue);
}
[TestMethod]
public void ShouldPeekAValue()
{
// arrange
var queue = GetQueue();
// act
bool isSuccess = queue.TryPeek(out var item);
// assert
Assert.IsTrue(isSuccess);
Assert.IsNotNull(item);
Assert.AreEqual(_queueElement1, item);
Assert.AreEqual(3, queue.Count);
}
[TestMethod]
public void ShouldNotPeekAValue()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
// act
bool isSuccess = queue.TryPeek(out var item);
// assert
Assert.IsFalse(isSuccess);
Assert.IsNull(item);
}
[TestMethod]
public void ShouldDequeueAValue()
{
// arrange
var queue = GetQueue();
// act
bool isSuccess = queue.TryDequeue(out var item);
// assert
Assert.IsTrue(isSuccess);
Assert.IsNotNull(item);
Assert.AreEqual(_queueElement1, item);
Assert.AreEqual(2, queue.Count);
}
[TestMethod]
public void ShouldNotDequeueAValue()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
// act
bool isSuccess = queue.TryDequeue(out var item);
// assert
Assert.IsFalse(isSuccess);
Assert.IsNull(item);
}
[TestMethod]
public void ShouldRemoveAValue()
{
// arrange
var queue = GetQueue();
// act
queue.Remove(_queueElement2);
var item1 = queue.Dequeue();
var item2 = queue.Dequeue();
// assert
Assert.AreEqual(0, queue.Count);
Assert.AreEqual(_queueElement1, item1);
Assert.AreEqual(_queueElement3, item2);
}
[TestMethod]
public void ShouldNotRemoveAValue()
{
// arrange
var queue = GetQueue();
// act
queue.Remove(null);
var item1 = queue.Dequeue();
var item2 = queue.Dequeue();
var item3 = queue.Dequeue();
// assert
Assert.AreEqual(0, queue.Count);
Assert.AreEqual(_queueElement1, item1);
Assert.AreEqual(_queueElement2, item2);
Assert.AreEqual(_queueElement3, item3);
}
[TestMethod]
public async Task ShouldAwaitOneDequeue()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
var task = Task.Run(async () =>
{
await Task.Delay(1000, TestContext.CancellationToken);
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
}, TestContext.CancellationToken);
// act
var item = await queue.DequeueAsync(TestContext.CancellationToken);
// assert
Assert.AreEqual(2, queue.Count);
Assert.IsNotNull(item);
Assert.AreEqual(_queueElement1, item);
}
[TestMethod]
public async Task ShouldAwaitManyDequeue()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
var task = Task.Run(async () =>
{
await Task.Delay(1000, TestContext.CancellationToken);
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
}, TestContext.CancellationToken);
// act
var items = await queue.DequeueManyAsync(2, TestContext.CancellationToken);
// assert
Assert.AreEqual(1, queue.Count);
Assert.IsNotNull(items);
Assert.HasCount(2, items);
Assert.AreEqual(_queueElement1, items[0]);
Assert.AreEqual(_queueElement2, items[1]);
}
[TestMethod]
public async Task ShouldAwaitAllDequeue()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
var task = Task.Run(async () =>
{
await Task.Delay(1000, TestContext.CancellationToken);
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
}, TestContext.CancellationToken);
// act
var items = await queue.DequeueAvailableAsync(cancellationToken: TestContext.CancellationToken);
// assert
Assert.AreEqual(0, queue.Count);
Assert.IsNotNull(items);
Assert.HasCount(3, items);
Assert.AreEqual(_queueElement1, items[0]);
Assert.AreEqual(_queueElement2, items[1]);
Assert.AreEqual(_queueElement3, items[2]);
}
[TestMethod]
public async Task ShouldAwaitAvailableDequeue()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
var task = Task.Run(async () =>
{
await Task.Delay(1000, TestContext.CancellationToken);
queue.Enqueue([_queueElement1, _queueElement2, _queueElement3]);
}, TestContext.CancellationToken);
// act
var items = await queue.DequeueAvailableAsync(2, TestContext.CancellationToken);
// assert
Assert.AreEqual(1, queue.Count);
Assert.IsNotNull(items);
Assert.HasCount(2, items);
Assert.AreEqual(_queueElement1, items[0]);
Assert.AreEqual(_queueElement2, items[1]);
}
[TestMethod]
public async Task ShouldThrowArumentOutOfRangeException()
{
// arrange
_internalQueue.Clear();
var queue = GetQueue();
// act & assert
await Assert.ThrowsExactlyAsync<ArgumentOutOfRangeException>(() => queue.DequeueManyAsync(-2, TestContext.CancellationToken));
}
private AsyncQueue<TestElement> GetQueue()
{
var asyncQueue = new AsyncQueue<TestElement>();
var field = asyncQueue.GetType().GetField("_queue", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(asyncQueue, _internalQueue);
return asyncQueue;
}
private class TestElement
{
public int Number { get; set; }
public string Text { get; set; }
}
}
}