From 01a8eac96bf81ce2d7a74fcd984060974c6ea88f Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 23 Apr 2024 18:51:07 +0000 Subject: [PATCH] add some simple tests --- .github/workflows/tests.yml | 8 ++-- tests/test_awaitable.py | 79 +++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ed7efc7..e278fd4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,11 +35,11 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install Ward - run: pip install --upgrade --pre ward + - name: Install PyTest + run: pip install --upgrade pytest pytest-memray pytest-asyncio - - name: Install project + - name: Build PyAwaitable run: pip install . - name: Run tests - run: ward + run: pytest --memray diff --git a/tests/test_awaitable.py b/tests/test_awaitable.py index f1a7618..30da282 100644 --- a/tests/test_awaitable.py +++ b/tests/test_awaitable.py @@ -1,12 +1,77 @@ -from ward import test import pyawaitable -import ctypes as ct +import ctypes from ctypes import pythonapi +import pytest +import asyncio get_pointer = pythonapi.PyCapsule_GetPointer -get_pointer.argtypes = (ct.py_object, ct.c_void_p) -get_pointer.restype = ct.c_void_p +get_pointer.argtypes = (ctypes.py_object, ctypes.c_void_p) +get_pointer.restype = ctypes.c_void_p -@test("awaitable creation") -async def _(): - ptr = get_pointer(pyawaitable._api, None) +awaitcallback = ctypes.CFUNCTYPE(ctypes.py_object, ctypes.py_object) +awaitcallback_err = awaitcallback + +# Initialize API array +ptr = get_pointer(pyawaitable._api, None) +api = (ctypes.c_void_p * 10).from_address(ptr) + +# Types +AwaitableType = ctypes.cast(api[0], ctypes.py_object).value +AwaitableGenWrapperType = ctypes.cast(api[1], ctypes.py_object).value + +# API Functions +awaitable_new = ctypes.cast(api[2], ctypes.CFUNCTYPE(ctypes.py_object)) +awaitable_await = ctypes.cast( + api[3], + ctypes.CFUNCTYPE( + ctypes.c_int, + ctypes.py_object, + ctypes.py_object, + awaitcallback, + awaitcallback_err, + ), +) + + +def test_api_types(): + assert AwaitableType is pyawaitable._awaitable + assert AwaitableGenWrapperType is pyawaitable._genwrapper + + +@pytest.mark.limit_leaks("5 KB") +@pytest.mark.asyncio +async def test_new(): + assert isinstance(awaitable_new(), pyawaitable._awaitable) + await asyncio.create_task(awaitable_new()) + await awaitable_new() + + +@pytest.mark.limit_leaks("5 KB") +@pytest.mark.asyncio +async def test_await(): + event = asyncio.Event() + + async def coro(): + event.set() + + awaitable = awaitable_new() + awaitable_await(awaitable, coro(), awaitcallback(0), awaitcallback_err(0)) + await awaitable + assert event.is_set() + + +@pytest.mark.limit_leaks("5 KB") +@pytest.mark.asyncio +async def test_await_cb(): + awaitable = awaitable_new() + + async def coro(value: int): + return value * 2 + + @awaitcallback + def cb(awaitable_inner: AwaitableType, result: int) -> int: + assert awaitable_inner is awaitable + assert result == 42 + return 0 + + awaitable_await(awaitable, coro(21), cb, awaitcallback_err(0))