Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,8 @@ async def async_coroutine(view):


class MyAsyncTestCase(AsyncTestCase):
timeout_ms = 4000
"""Class wide coroutine timeout."""

@classmethod
async def setUpClass(cls):
Expand All @@ -613,7 +615,10 @@ class MyAsyncTestCase(AsyncTestCase):
"Initial Content"
)

async def test_coroutine(self):
async def test_coroutine(self, timeout_ms=10000):
"""
A long running coroutine with custom timeout.
"""
await async_coroutine(self.view)
self.assertEqual(
self.view.substr(sublime.Region(0, self.view.size())),
Expand Down
3 changes: 0 additions & 3 deletions tests/_Asyncio/unittesting.json

This file was deleted.

File renamed without changes.
1 change: 1 addition & 0 deletions tests/_Asyncio_Timeout/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.8
19 changes: 19 additions & 0 deletions tests/_Asyncio_Timeout/tests/test_coroutine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import asyncio

from unittesting import AsyncTestCase


async def a_coro(test):
await asyncio.sleep(1.0)


class MyAsyncTestCaseA(AsyncTestCase):
timeout_ms = 100

async def test_coroutine_class_timeout(self):
await a_coro(self)


class MyAsyncTestCaseB(AsyncTestCase):
async def test_coroutine_local_timeout(self, timeout_ms=100):
await a_coro(self)
12 changes: 9 additions & 3 deletions tests/test_3141596.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ def assertOk(self, txt, msg=None):

class TestUnitTesting(UnitTestingTestCase):
fixtures = (
"_Success", "_Failure", "_Empty", "_Output", "_Deferred", "_Async", "_Asyncio"
"_Success", "_Failure", "_Empty", "_Output", "_Deferred", "_Async",
"_Asyncio_Success", "_Asyncio_Timeout"
)

@with_package("_Success")
Expand Down Expand Up @@ -154,10 +155,15 @@ def test_async(self, txt):
self.assertOk(txt)

@skipIf(PY33, "not applicable in Python 3.3")
@with_package("_Asyncio")
def test_asyncio(self, txt):
@with_package("_Asyncio_Success")
def test_asyncio_success(self, txt):
self.assertOk(txt)

@skipIf(PY33, "not applicable in Python 3.3")
@with_package("_Asyncio_Timeout")
def test_asyncio_timeout(self, txt):
self.assertRegexContains(txt, r'^ERROR')


class TestSyntax(UnitTestingTestCase):
fixtures = (
Expand Down
15 changes: 13 additions & 2 deletions unittesting/core/py313/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from unittest.case import _Outcome
from unittest.case import expectedFailure

from .runner import DEFAULT_CONDITION_TIMEOUT
from .runner import defer

__all__ = [
Expand All @@ -22,6 +23,7 @@


class DeferrableTestCase(TestCase):
timeout_ms: int = DEFAULT_CONDITION_TIMEOUT

def _callSetUp(self):
return self._callMaybeCoro(self.setUp)
Expand All @@ -48,15 +50,24 @@ def _callMaybeCoro(cls, func, /, *args, **kwargs):
elif inspect.iscoroutine(coro):
fut = cls.run_coroutine(coro)

def wait_until_complete():
def await_future():
if not fut.done() and not fut.cancelled():
return False
exception = fut.exception()
if exception is not None:
raise exception from None
return True

yield wait_until_complete
if frame := coro.cr_frame:
# prefer optional timeout from test_... coroutine's arguments
timeout_ms = frame.f_locals.get("timeout_ms", cls.timeout_ms)
else:
timeout_ms = cls.timeout_ms
try:
yield {"condition": await_future, "timeout": timeout_ms}
except TimeoutError:
msg = f"Task not completed within {timeout_ms / 1000:.2f} seconds."
coro.throw(TimeoutError, msg)

@staticmethod
def run_coroutine(coro):
Expand Down
15 changes: 13 additions & 2 deletions unittesting/core/py38/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from unittest.case import _Outcome
from unittest.case import expectedFailure

from .runner import DEFAULT_CONDITION_TIMEOUT
from .runner import defer

__all__ = [
Expand All @@ -21,6 +22,7 @@


class DeferrableTestCase(TestCase):
timeout_ms: int = DEFAULT_CONDITION_TIMEOUT

def _callSetUp(self):
return self._callMaybeCoro(self.setUp)
Expand All @@ -47,15 +49,24 @@ def _callMaybeCoro(cls, func, /, *args, **kwargs):
elif inspect.iscoroutine(coro):
fut = cls.run_coroutine(coro)

def wait_until_complete():
def await_future():
if not fut.done() and not fut.cancelled():
return False
exception = fut.exception()
if exception is not None:
raise exception from None
return True

yield wait_until_complete
if frame := coro.cr_frame:
# prefer optional timeout from test_... coroutine's arguments
timeout_ms = frame.f_locals.get("timeout_ms", cls.timeout_ms)
else:
timeout_ms = cls.timeout_ms
try:
yield {"condition": await_future, "timeout": timeout_ms}
except TimeoutError:
msg = f"Task not completed within {timeout_ms / 1000:.2f} seconds."
coro.throw(TimeoutError, msg)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn’t know this .throw was possible. Very cool!


@staticmethod
def run_coroutine(coro):
Expand Down
Loading