# #region TestAsyncTaskManager [C:3] [TYPE Module] [SEMANTICS test, task_manager, async, concurrency]
# @BRIEF Tests for async TaskManager — concurrent execution, cancellation.
# @RELATION BINDS_TO -> [TaskManager]
# @TEST_EDGE: concurrent_block -> Two tasks must run concurrently, not sequentially
# @TEST_EDGE: cancellation -> Cancelled task must propagate CancelledError
import asyncio
import pytest


# #region test_concurrent_tasks_dont_block [C:2] [TYPE Function]
# @BRIEF Verify two async tasks run concurrently via asyncio.gather, not sequentially.
@pytest.mark.asyncio
async def test_concurrent_tasks_dont_block():
    results = []

    async def task_a():
        await asyncio.sleep(0.05)
        results.append("A")
        return "A"

    async def task_b():
        await asyncio.sleep(0.03)
        results.append("B")
        return "B"

    t0 = asyncio.get_event_loop().time()
    a, b = await asyncio.gather(task_a(), task_b())
    elapsed = asyncio.get_event_loop().time() - t0

    assert elapsed < 0.08, f"Not concurrent: {elapsed:.3f}s"
    assert a == "A" and b == "B"
    assert len(results) == 2
# #endregion test_concurrent_tasks_dont_block


# #region test_task_cancellation [C:2] [TYPE Function]
# @BRIEF Verify asyncio task cancellation propagates CancelledError to caller.
@pytest.mark.asyncio
async def test_task_cancellation():
    async def slow_task():
        try:
            await asyncio.sleep(10)
            return "done"
        except asyncio.CancelledError:
            return "cancelled"

    task = asyncio.create_task(slow_task())
    await asyncio.sleep(0.01)
    task.cancel()
    result = await task
    assert result == "cancelled"
# #endregion test_task_cancellation


# #endregion TestAsyncTaskManager
