diff --git a/decoy/__init__.py b/decoy/__init__.py index 7036e73..03ec9f2 100644 --- a/decoy/__init__.py +++ b/decoy/__init__.py @@ -4,6 +4,7 @@ TYPE_CHECKING, Any, Callable, + Coroutine, Generic, Optional, Union, @@ -195,6 +196,9 @@ def verify( the actual call. Decoy will compare and match any given arguments, ignoring unspecified arguments. + Raises: + VerifyError: The verification was not satisfied. + Example: ```python def test_create_something(decoy: Decoy): @@ -278,12 +282,20 @@ def then_raise(self, error: Exception) -> None: """ self._core.then_raise(error) - def then_do(self, action: Callable[..., ReturnT]) -> None: + def then_do( + self, + action: Callable[..., Union[ReturnT, Coroutine[Any, Any, ReturnT]]], + ) -> None: """Configure the stub to trigger an action. Arguments: action: The function to call. Called with whatever arguments - are actually passed to the stub. + are actually passed to the stub. May be an `async def` + function if the mock is also asynchronous. + + Raises: + MockNotAsyncError: `action` was an `async def` function, + but the mock is synchronous. """ self._core.then_do(action) diff --git a/decoy/core.py b/decoy/core.py index 375cbbe..6b8935a 100644 --- a/decoy/core.py +++ b/decoy/core.py @@ -1,7 +1,9 @@ """Decoy implementation logic.""" +import inspect from typing import Any, Callable, Optional from .call_handler import CallHandler +from .errors import MockNotAsyncError from .spy import SpyCreator from .spy_events import WhenRehearsal, PropAccessType, SpyEvent, SpyInfo, SpyPropAccess from .spy_log import SpyLog @@ -111,6 +113,14 @@ def then_raise(self, error: Exception) -> None: def then_do(self, action: Callable[..., ReturnT]) -> None: """Set the stub to perform an action.""" + spy_info = self._rehearsal.spy + + if inspect.iscoroutinefunction(action) and not spy_info.is_async: + raise MockNotAsyncError( + f"Cannot configure {spy_info.name} to call {action}" + f" because {spy_info.name} is not asynchronous." + ) + self._stub_store.add( rehearsal=self._rehearsal, behavior=StubBehavior(action=action), diff --git a/decoy/errors.py b/decoy/errors.py index 944258f..2186a8d 100644 --- a/decoy/errors.py +++ b/decoy/errors.py @@ -27,6 +27,17 @@ def __init__(self) -> None: super().__init__("Rehearsal not found.") +class MockNotAsyncError(TypeError): + """An error raised when an asynchronous function is used with a synchronous mock. + + This error is raised if you pass an `async def` function + to a synchronous stub's `then_do` method. + See the [MockNotAsyncError guide][] for more details. + + [MockNotAsyncError guide]: ../usage/errors-and-warnings/#mocknotasyncerror + """ + + class VerifyError(AssertionError): """An error raised when actual calls do not match rehearsals given to `verify`. diff --git a/decoy/spy.py b/decoy/spy.py index 1efc4ff..17b35a1 100644 --- a/decoy/spy.py +++ b/decoy/spy.py @@ -3,6 +3,7 @@ Classes in this module are heavily inspired by the [unittest.mock library](https://docs.python.org/3/library/unittest.mock.html). """ +import inspect from types import TracebackType from typing import Any, ContextManager, Dict, Optional, Type, Union, cast, overload @@ -155,7 +156,8 @@ class AsyncSpy(BaseSpy): async def __call__(self, *args: Any, **kwargs: Any) -> Any: """Handle a call to the spy asynchronously.""" - return self._call(*args, **kwargs) + result = self._call(*args, **kwargs) + return (await result) if inspect.iscoroutine(result) else result class Spy(BaseSpy): diff --git a/decoy/spy_core.py b/decoy/spy_core.py index df61205..3390538 100644 --- a/decoy/spy_core.py +++ b/decoy/spy_core.py @@ -1,4 +1,4 @@ -"""Mock specification.""" +"""Core spy logic.""" import inspect import functools import warnings @@ -27,7 +27,7 @@ class BoundArgs(NamedTuple): class SpyCore: - """Spy configuration values. + """Core spy logic for mimicing a given `source` object. Arguments: source: The source object the Spy is mimicing. @@ -55,10 +55,10 @@ def __init__( self._full_name = ( f"{self._module_name}.{self._name}" if self._module_name else self._name ) - self._info = SpyInfo(id=id(self), name=self._name) self._class_type = self._source if inspect.isclass(self._source) else None self._signature = _get_signature(source) self._is_async = is_async or _get_is_async(source) + self._info = SpyInfo(id=id(self), name=self._name, is_async=self._is_async) @property def info(self) -> SpyInfo: diff --git a/decoy/spy_events.py b/decoy/spy_events.py index 0e272be..69b8d1c 100644 --- a/decoy/spy_events.py +++ b/decoy/spy_events.py @@ -16,6 +16,7 @@ class SpyInfo(NamedTuple): id: int name: str + is_async: bool class SpyCall(NamedTuple): diff --git a/docs/usage/errors-and-warnings.md b/docs/usage/errors-and-warnings.md index e6fa1c6..d4d8bb1 100644 --- a/docs/usage/errors-and-warnings.md +++ b/docs/usage/errors-and-warnings.md @@ -27,8 +27,24 @@ decoy.when().then_return(42) # raises a MissingRehearsalError If you're working with async/await code, this can also happen if you forget to include `await` in your rehearsal, because the `await` is necessary for the spy's call handler to add the call to the stack. ```python -decoy.when(some_async_func("hello")).then_return("world") # will raise decoy.when(await some_async_func("hello")).then_return("world") # all good +decoy.when(some_async_func("hello")).then_return("world") # will raise +``` + +### MockNotAsyncError + +A [decoy.errors.MockNotAsyncError][] will be raised if you pass an `async def` function to [decoy.Stub.then_do][] of a non-synchronous mock. + +```python +async_mock = decoy.mock(name="async_mock", is_async=True) +async_mock = decoy.mock(name="sync_mock") + +async def _handle_call(input: str) -> str: + print(input) + return "world" + +decoy.when(await async_mock("hello")).then_do(_handle_call) # all good +decoy.when(sync_mock("hello")).then_do(_handle_call) # will raise ``` ## Warnings diff --git a/tests/common.py b/tests/fixtures.py similarity index 98% rename from tests/common.py rename to tests/fixtures.py index 765736d..08ddbe7 100644 --- a/tests/common.py +++ b/tests/fixtures.py @@ -1,4 +1,4 @@ -"""Common test interfaces.""" +"""Common test fixtures.""" from functools import lru_cache from typing import Any diff --git a/tests/test_call_handler.py b/tests/test_call_handler.py index 5ce5c53..37acd20 100644 --- a/tests/test_call_handler.py +++ b/tests/test_call_handler.py @@ -41,7 +41,8 @@ def test_handle_call_with_no_stubbing( ) -> None: """It should noop and add the call to the stack if no stubbing is configured.""" spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="spy_name", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior = None @@ -61,7 +62,8 @@ def test_handle_call_with_return( ) -> None: """It return a Stub's configured return value.""" spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="spy_name", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior = StubBehavior(return_value="hello world") @@ -81,7 +83,8 @@ def test_handle_call_with_raise( ) -> None: """It raise a Stub's configured error.""" spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="spy_name", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior = StubBehavior(error=RuntimeError("oh no")) @@ -102,7 +105,7 @@ def test_handle_call_with_action( """It should trigger a stub's configured action.""" action = decoy.mock() spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), + spy=SpyInfo(id=42, name="spy_name", is_async=False), payload=SpyCall(args=(1,), kwargs={"foo": "bar"}), ) behavior = StubBehavior(action=action) @@ -124,7 +127,7 @@ def test_handle_prop_get_with_action( """It should trigger a prop get stub's configured action.""" action = decoy.mock() spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), + spy=SpyInfo(id=42, name="spy_name", is_async=False), payload=SpyPropAccess(prop_name="prop", access_type=PropAccessType.GET), ) behavior = StubBehavior(action=action) @@ -145,7 +148,7 @@ def test_handle_call_with_context_enter( ) -> None: """It should return a Stub's configured context value.""" spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), + spy=SpyInfo(id=42, name="spy_name", is_async=False), payload=SpyCall(args=(), kwargs={}), ) behavior = StubBehavior(context_value="hello world") @@ -166,7 +169,7 @@ def test_handle_call_with_context_enter_none( ) -> None: """It should allow a configured context value to be None.""" spy_call = SpyEvent( - spy=SpyInfo(id=42, name="spy_name"), + spy=SpyInfo(id=42, name="spy_name", is_async=False), payload=SpyCall(args=(), kwargs={}), ) behavior = StubBehavior(context_value=None) diff --git a/tests/test_core.py b/tests/test_core.py index 33bae94..5df0e62 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -6,7 +6,7 @@ from decoy.spy_log import SpyLog from decoy.core import DecoyCore -# from decoy.errors import MockNotAsyncError +from decoy.errors import MockNotAsyncError from decoy.spy import Spy, SpyCreator from decoy.spy_events import ( SpyInfo, @@ -22,7 +22,9 @@ from decoy.verifier import Verifier from decoy.warning_checker import WarningChecker -from .common import SomeClass +from .fixtures import SomeClass + +pytestmark = pytest.mark.asyncio @pytest.fixture() @@ -143,7 +145,8 @@ def test_when_then_return( ) -> None: """It should be able to register a new stubbing.""" rehearsal = WhenRehearsal( - spy=SpyInfo(id=1, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( rehearsal @@ -168,7 +171,8 @@ def test_when_then_return_multiple_values( ) -> None: """It should add multiple return values to a stub.""" rehearsal = WhenRehearsal( - spy=SpyInfo(id=1, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( rehearsal @@ -201,7 +205,8 @@ def test_when_then_raise( ) -> None: """It should add a raise behavior to a stub.""" rehearsal = WhenRehearsal( - spy=SpyInfo(id=1, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( rehearsal @@ -227,7 +232,7 @@ def test_when_then_do( ) -> None: """It should add an action behavior to a stub.""" rehearsal = WhenRehearsal( - spy=SpyInfo(id=1, name="my_spy"), + spy=SpyInfo(id=1, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( @@ -246,6 +251,59 @@ def test_when_then_do( ) +def test_when_then_do_async( + decoy: Decoy, + spy_log: SpyLog, + stub_store: StubStore, + subject: DecoyCore, +) -> None: + """It should add an async action behavior to an async stub.""" + rehearsal = WhenRehearsal( + spy=SpyInfo(id=1, name="my_spy", is_async=True), + payload=SpyCall(args=(), kwargs={}), + ) + decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( + rehearsal + ) + + async def action() -> str: + ... + + result = subject.when("__rehearsal__", ignore_extra_args=False) + result.then_do(action) + + decoy.verify( + stub_store.add( + rehearsal=rehearsal, + behavior=StubBehavior(action=action), + ) + ) + + +async def test_when_then_do_async_not_allowed( + decoy: Decoy, + spy_log: SpyLog, + stub_store: StubStore, + subject: DecoyCore, +) -> None: + """It should disallow an async action behavior with a sync stub.""" + rehearsal = WhenRehearsal( + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), + ) + decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( + rehearsal + ) + + async def action() -> str: + ... + + result = subject.when("__rehearsal__", ignore_extra_args=False) + + with pytest.raises(MockNotAsyncError): + result.then_do(action) + + def test_when_then_enter_with( decoy: Decoy, spy_log: SpyLog, @@ -254,7 +312,8 @@ def test_when_then_enter_with( ) -> None: """It should be able to register a ContextManager stubbing.""" rehearsal = WhenRehearsal( - spy=SpyInfo(id=1, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=False)).then_return( rehearsal @@ -279,7 +338,8 @@ def test_when_ignore_extra_args( ) -> None: """It should be able to register a new stubbing.""" rehearsal = WhenRehearsal( - spy=SpyInfo(id=1, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.consume_when_rehearsal(ignore_extra_args=True)).then_return( rehearsal @@ -305,10 +365,12 @@ def test_verify( """It should be able to verify a call.""" spy_id = 42 rehearsal = VerifyRehearsal( - spy=SpyInfo(id=spy_id, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call = SpyEvent( - spy=SpyInfo(id=spy_id, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when( @@ -334,15 +396,18 @@ def test_verify_multiple_calls( rehearsals = [ VerifyRehearsal( - spy=SpyInfo(id=spy_id_1, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id_1, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=spy_id_2, name="spy_2"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id_2, name="spy_2", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ] calls = [ SpyEvent( - spy=SpyInfo(id=spy_id_1, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id_1, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) ] @@ -370,10 +435,12 @@ def test_verify_call_times( """It should be able to verify the call count.""" spy_id = 42 rehearsal = VerifyRehearsal( - spy=SpyInfo(id=spy_id, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call = SpyEvent( - spy=SpyInfo(id=spy_id, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=spy_id, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when( @@ -393,7 +460,7 @@ def test_prop( ) -> None: """It should be able to create set and delete rehearsals.""" rehearsal = PropRehearsal( - spy=SpyInfo(id=1, name="my_spy"), + spy=SpyInfo(id=1, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="my_prop", access_type=PropAccessType.GET), ) @@ -404,7 +471,7 @@ def test_prop( result.set("hello") expected_set_event = SpyEvent( - spy=SpyInfo(id=1, name="my_spy"), + spy=SpyInfo(id=1, name="my_spy", is_async=False), payload=SpyPropAccess( prop_name="my_prop", access_type=PropAccessType.SET, @@ -416,7 +483,7 @@ def test_prop( result.delete() expected_delete_event = SpyEvent( - spy=SpyInfo(id=1, name="my_spy"), + spy=SpyInfo(id=1, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="my_prop", access_type=PropAccessType.DELETE), ) decoy.verify(spy_log.push(expected_delete_event), times=1) @@ -431,7 +498,8 @@ def test_reset( ) -> None: """It should reset the stores.""" call = SpyEvent( - spy=SpyInfo(id=1, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) decoy.when(spy_log.get_all()).then_return([call]) diff --git a/tests/test_decoy.py b/tests/test_decoy.py index 18d49ae..0fac274 100644 --- a/tests/test_decoy.py +++ b/tests/test_decoy.py @@ -8,7 +8,13 @@ from decoy import Decoy, errors from decoy.spy import AsyncSpy, Spy -from .common import SomeAsyncClass, SomeClass, SomeNestedClass, some_func +from .fixtures import ( + SomeAsyncClass, + SomeClass, + SomeNestedClass, + some_func, + some_async_func, +) pytestmark = pytest.mark.asyncio @@ -111,6 +117,23 @@ def _then_do_action(arg: str) -> str: assert result == "hello from the other side" +async def test_when_then_do_async(decoy: Decoy) -> None: + """It should be able to configure a stub action with a rehearsal.""" + subject = decoy.mock(func=some_async_func) + action_result = None + + async def _then_do_action(arg: str) -> str: + nonlocal action_result + action_result = arg + return "hello from the other side" + + decoy.when(await subject("what's up")).then_do(_then_do_action) + + result = await subject("what's up") + assert action_result == "what's up" + assert result == "hello from the other side" + + def test_when_ignore_extra_args(decoy: Decoy) -> None: """It should be able to ignore extra args in a stub rehearsal.""" diff --git a/tests/test_errors.py b/tests/test_errors.py index d1b4ecd..10fd65e 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -20,7 +20,8 @@ class VerifyErrorSpec(NamedTuple): VerifyErrorSpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], calls=[], @@ -36,16 +37,17 @@ class VerifyErrorSpec(NamedTuple): VerifyErrorSpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), ], @@ -63,29 +65,29 @@ class VerifyErrorSpec(NamedTuple): VerifyErrorSpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=("oh no",), kwargs={}), ), ], @@ -106,17 +108,17 @@ class VerifyErrorSpec(NamedTuple): VerifyErrorSpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], @@ -132,13 +134,13 @@ class VerifyErrorSpec(NamedTuple): VerifyErrorSpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), ], diff --git a/tests/test_matchers.py b/tests/test_matchers.py index e69c4e2..d7d2f78 100644 --- a/tests/test_matchers.py +++ b/tests/test_matchers.py @@ -3,7 +3,7 @@ from collections import namedtuple from decoy import Decoy, matchers from typing import Any, List, NamedTuple -from .common import SomeClass +from .fixtures import SomeClass class _HelloClass(NamedTuple): diff --git a/tests/test_spy.py b/tests/test_spy.py index 38baec5..c0e4b77 100644 --- a/tests/test_spy.py +++ b/tests/test_spy.py @@ -2,6 +2,7 @@ import pytest import inspect import sys + from decoy import Decoy from decoy.call_handler import CallHandler, CallHandlerResult @@ -9,7 +10,7 @@ from decoy.spy_core import BoundArgs, SpyCore from decoy.spy_events import SpyCall, SpyEvent, SpyInfo, SpyPropAccess, PropAccessType -from .common import SomeClass, some_func +from .fixtures import SomeClass, some_func pytestmark = pytest.mark.asyncio @@ -125,7 +126,7 @@ def test_spy_calls( spy_core: SpyCore, ) -> None: """It should send any calls to the call handler.""" - spy_info = SpyInfo(id=123456, name="spy_name") + spy_info = SpyInfo(id=123456, name="spy_name", is_async=False) decoy.when(spy_core.info).then_return(spy_info) decoy.when(spy_core.bind_args(1, 2, three=3)).then_return( @@ -146,6 +147,43 @@ def test_spy_calls( assert result == 42 +async def test_async_spy_calls( + decoy: Decoy, + call_handler: CallHandler, + spy_creator: SpyCreator, + spy_core: SpyCore, +) -> None: + """It should understand async returns from the call handler.""" + spy_info = SpyInfo(id=123456, name="spy_name", is_async=True) + + async def _get_call_result() -> int: + return 42 + + decoy.when(spy_core.info).then_return(spy_info) + decoy.when(spy_core.bind_args(1, 2, three=3)).then_return( + BoundArgs(args=(1, 2, 3), kwargs={}) + ) + + subject = AsyncSpy( + core=spy_core, + call_handler=call_handler, + spy_creator=spy_creator, + ) + + decoy.when( + call_handler.handle( + SpyEvent( + spy=spy_info, + payload=SpyCall(args=(1, 2, 3), kwargs={}), + ) + ) + ).then_return(CallHandlerResult(_get_call_result())) + + result = await subject(1, 2, three=3) + + assert result == 42 + + def test_spy_context_manager( decoy: Decoy, call_handler: CallHandler, @@ -227,7 +265,7 @@ def test_spy_prop_get( spy_core: SpyCore, ) -> None: """It should record a property get call.""" - spy_info = SpyInfo(id=123456, name="spy_name") + spy_info = SpyInfo(id=123456, name="spy_name", is_async=False) decoy.when(spy_core.info).then_return(spy_info) decoy.when( @@ -255,7 +293,7 @@ def test_spy_prop_set( spy_core: SpyCore, ) -> None: """It should record a property set call.""" - spy_info = SpyInfo(id=123456, name="spy_name") + spy_info = SpyInfo(id=123456, name="spy_name", is_async=False) decoy.when(spy_core.info).then_return(spy_info) @@ -284,7 +322,7 @@ def test_spy_prop_delete( spy_core: SpyCore, ) -> None: """It should record a property set call.""" - spy_info = SpyInfo(id=123456, name="spy_name") + spy_info = SpyInfo(id=123456, name="spy_name", is_async=False) decoy.when(spy_core.info).then_return(spy_info) diff --git a/tests/test_spy_core.py b/tests/test_spy_core.py index eedb955..e6e6005 100644 --- a/tests/test_spy_core.py +++ b/tests/test_spy_core.py @@ -5,7 +5,7 @@ from decoy.spy_core import SpyCore, BoundArgs from decoy.warnings import IncorrectCallWarning -from .common import ( +from .fixtures import ( SomeClass, SomeAsyncClass, SomeAsyncCallableClass, @@ -48,7 +48,7 @@ class GetNameSpec(NamedTuple): GetNameSpec( subject=SpyCore(source=some_func, name=None), expected_name="some_func", - expected_full_name="tests.common.some_func", + expected_full_name="tests.fixtures.some_func", ), GetNameSpec( subject=SpyCore( @@ -67,7 +67,7 @@ class GetNameSpec(NamedTuple): "foo", is_async=False ), expected_name="SomeClass.foo", - expected_full_name="tests.common.SomeClass.foo", + expected_full_name="tests.fixtures.SomeClass.foo", ), GetNameSpec( subject=( @@ -76,7 +76,7 @@ class GetNameSpec(NamedTuple): .create_child_core("foo", is_async=False) ), expected_name="SomeNestedClass.child.foo", - expected_full_name="tests.common.SomeNestedClass.child.foo", + expected_full_name="tests.fixtures.SomeNestedClass.child.foo", ), ], ) diff --git a/tests/test_spy_events.py b/tests/test_spy_events.py index c7b2ebe..8c0b94f 100644 --- a/tests/test_spy_events.py +++ b/tests/test_spy_events.py @@ -26,99 +26,99 @@ class MatchEventSpec(NamedTuple): match_event_specs: List[MatchEventSpec] = [ MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), expected_result=True, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), rehearsal=VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), expected_result=True, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1,), kwargs={"baz": "qux"}, ignore_extra_args=True), ), expected_result=True, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), rehearsal=VerifyRehearsal( - spy=SpyInfo(id=21, name="my_spy"), + spy=SpyInfo(id=21, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), expected_result=False, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), expected_result=False, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), rehearsal=VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), expected_result=False, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(2,), kwargs={"baz": "qux"}, ignore_extra_args=True), ), expected_result=False, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), rehearsal=VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "qux"}, ignore_extra_args=True), ), expected_result=False, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall( args=(1, 2, 3), kwargs={"foo": "bar", "baz": "qux"}, @@ -129,11 +129,11 @@ class MatchEventSpec(NamedTuple): ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2), kwargs={"foo": "bar", "baz": "qux"}), ), rehearsal=VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall( args=(1, 2), kwargs={"foo": "bar", "baz": "qux", "fizz": "buzz"}, @@ -144,22 +144,22 @@ class MatchEventSpec(NamedTuple): ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="prop", access_type=PropAccessType.GET), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="prop", access_type=PropAccessType.GET), ), expected_result=True, ), MatchEventSpec( event=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="prop", access_type=PropAccessType.DELETE), ), rehearsal=WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="prop", access_type=PropAccessType.GET), ), expected_result=False, diff --git a/tests/test_spy_log.py b/tests/test_spy_log.py index 97fb080..4c61f1f 100644 --- a/tests/test_spy_log.py +++ b/tests/test_spy_log.py @@ -19,7 +19,7 @@ def test_push_and_consume_when_rehearsal() -> None: """It should be able to push and pop from the stack.""" subject = SpyLog() call = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ) @@ -34,7 +34,7 @@ def test_push_and_consume_when_rehearsal_ignore_extra_args() -> None: """It should be able to push and pop from the stack while ignoring extra args.""" subject = SpyLog() call = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ) @@ -50,7 +50,7 @@ def test_push_and_consume_prop_rehearsal_for_when() -> None: """It should be able to push and consume a prop rehearsal for stubbing.""" subject = SpyLog() event = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="my_prop", access_type=PropAccessType.GET), ) @@ -68,7 +68,7 @@ def test_consume_when_rehearsal_raises_empty_error() -> None: subject.consume_when_rehearsal(ignore_extra_args=False) call = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ) subject.push(call) @@ -82,7 +82,7 @@ def test_push_and_consume_prop_rehearsal_for_prop() -> None: """It should be able to push and consume a prop rehearsal for more rehearsals.""" subject = SpyLog() event = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="my_prop", access_type=PropAccessType.GET), ) @@ -100,7 +100,7 @@ def test_consume_prop_rehearsal_raises_empty_error() -> None: subject.consume_prop_rehearsal() event = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="my_prop", access_type=PropAccessType.GET), ) subject.push(event) @@ -110,7 +110,7 @@ def test_consume_prop_rehearsal_raises_empty_error() -> None: subject.consume_prop_rehearsal() call = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ) subject.push(call) @@ -119,7 +119,7 @@ def test_consume_prop_rehearsal_raises_empty_error() -> None: subject.consume_prop_rehearsal() event = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyPropAccess(prop_name="my_prop", access_type=PropAccessType.DELETE), ) subject.push(event) @@ -132,10 +132,12 @@ def test_consume_verify_rehearsals() -> None: """It should be able to pop a slice off the stack, retaining order.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=1, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call_2 = SpyEvent( - spy=SpyInfo(id=2, name="spy_2"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=2, name="spy_2", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) subject.push(call_1) @@ -144,11 +146,11 @@ def test_consume_verify_rehearsals() -> None: result = subject.consume_verify_rehearsals(count=2, ignore_extra_args=False) assert result == [ VerifyRehearsal( - spy=SpyInfo(id=1, name="spy_1"), + spy=SpyInfo(id=1, name="spy_1", is_async=False), payload=SpyCall(args=(), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=2, name="spy_2"), + spy=SpyInfo(id=2, name="spy_2", is_async=False), payload=SpyCall(args=(), kwargs={}), ), ] @@ -164,10 +166,12 @@ def test_consume_verify_rehearsals_ignore_extra_args() -> None: """It should be able to pop a slice off the stack, retaining order.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=1, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call_2 = SpyEvent( - spy=SpyInfo(id=2, name="spy_2"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=2, name="spy_2", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) subject.push(call_1) @@ -176,11 +180,11 @@ def test_consume_verify_rehearsals_ignore_extra_args() -> None: result = subject.consume_verify_rehearsals(count=2, ignore_extra_args=True) assert result == [ VerifyRehearsal( - spy=SpyInfo(id=1, name="spy_1"), + spy=SpyInfo(id=1, name="spy_1", is_async=False), payload=SpyCall(args=(), kwargs={}, ignore_extra_args=True), ), VerifyRehearsal( - spy=SpyInfo(id=2, name="spy_2"), + spy=SpyInfo(id=2, name="spy_2", is_async=False), payload=SpyCall(args=(), kwargs={}, ignore_extra_args=True), ), ] @@ -190,18 +194,19 @@ def test_consume_verify_rehearsals_ignores_prop_gets() -> None: """It should be able to pop a slice off the stack, retaining order.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=101, name="spy_1", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ) call_2 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyPropAccess(prop_name="child", access_type=PropAccessType.GET), ) call_3 = SpyEvent( - spy=SpyInfo(id=102, name="spy_1.child"), + spy=SpyInfo(id=102, name="spy_1.child", is_async=False), payload=SpyCall(args=(2,), kwargs={}), ) call_4 = SpyEvent( - spy=SpyInfo(id=102, name="spy_1.child"), + spy=SpyInfo(id=102, name="spy_1.child", is_async=False), payload=SpyPropAccess(prop_name="fizz", access_type=PropAccessType.DELETE), ) subject.push(call_1) @@ -212,15 +217,15 @@ def test_consume_verify_rehearsals_ignores_prop_gets() -> None: result = subject.consume_verify_rehearsals(count=3, ignore_extra_args=False) assert result == [ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=102, name="spy_1.child"), + spy=SpyInfo(id=102, name="spy_1.child", is_async=False), payload=SpyCall(args=(2,), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=102, name="spy_1.child"), + spy=SpyInfo(id=102, name="spy_1.child", is_async=False), payload=SpyPropAccess(prop_name="fizz", access_type=PropAccessType.DELETE), ), ] @@ -230,7 +235,8 @@ def test_consume_verify_rehearsals_raises_error() -> None: """It should raise an error if the stack has too few members to pop a slice.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=1, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) subject.push(call_1) @@ -243,19 +249,19 @@ def test_get_calls_to_verify() -> None: """It can get a list of calls made matching spy IDs of given rehearsals.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ) call_2 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyCall(args=(2,), kwargs={}), ) call_3 = SpyEvent( - spy=SpyInfo(id=202, name="spy_2"), + spy=SpyInfo(id=202, name="spy_2", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ) call_4 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ) @@ -280,19 +286,19 @@ def test_get_calls_to_verify_skips_prop_gets() -> None: subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyPropAccess(prop_name="child", access_type=PropAccessType.GET), ) call_2 = PropRehearsal( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyPropAccess(prop_name="child", access_type=PropAccessType.GET), ) call_3 = SpyEvent( - spy=SpyInfo(id=102, name="spy_1.child"), + spy=SpyInfo(id=102, name="spy_1.child", is_async=False), payload=SpyCall(args=(2,), kwargs={}), ) call_4 = SpyEvent( - spy=SpyInfo(id=102, name="spy_1.child"), + spy=SpyInfo(id=102, name="spy_1.child", is_async=False), payload=SpyPropAccess(prop_name="fizz", access_type=PropAccessType.DELETE), ) @@ -308,13 +314,16 @@ def test_get_all() -> None: """It can get a list of all calls and rehearsals.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=101, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call_2 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=101, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call_3 = SpyEvent( - spy=SpyInfo(id=202, name="spy_2"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=202, name="spy_2", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) subject.push(call_1) @@ -325,15 +334,16 @@ def test_get_all() -> None: assert subject.get_all() == [ WhenRehearsal( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), + spy=SpyInfo(id=101, name="spy_1", is_async=False), payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=202, name="spy_2"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=202, name="spy_2", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ] @@ -342,13 +352,16 @@ def test_clear() -> None: """It can clear all calls and rehearsals.""" subject = SpyLog() call_1 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=101, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call_2 = SpyEvent( - spy=SpyInfo(id=101, name="spy_1"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=101, name="spy_1", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) call_3 = SpyEvent( - spy=SpyInfo(id=202, name="spy_2"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=202, name="spy_2", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) subject.push(call_1) diff --git a/tests/test_stringify.py b/tests/test_stringify.py index 2cb81f5..0d3a4a9 100644 --- a/tests/test_stringify.py +++ b/tests/test_stringify.py @@ -16,35 +16,35 @@ class StringifyCallSpec(NamedTuple): stringify_call_specs = [ StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some.name"), + spy=SpyInfo(id=42, name="some.name", is_async=False), payload=SpyCall(args=(), kwargs={}), ), expected="some.name()", ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some.name"), + spy=SpyInfo(id=42, name="some.name", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), expected="some.name(1)", ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some.name"), + spy=SpyInfo(id=42, name="some.name", is_async=False), payload=SpyCall(args=(1, "2"), kwargs={}), ), expected="some.name(1, '2')", ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some.name"), + spy=SpyInfo(id=42, name="some.name", is_async=False), payload=SpyCall(args=(), kwargs={"foo": "bar"}), ), expected="some.name(foo='bar')", ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some.name"), + spy=SpyInfo(id=42, name="some.name", is_async=False), payload=SpyCall( args=(1, 2), kwargs={"foo": "bar", "baz": False}, @@ -54,7 +54,7 @@ class StringifyCallSpec(NamedTuple): ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some.name"), + spy=SpyInfo(id=42, name="some.name", is_async=False), payload=SpyCall( args=(), kwargs={}, @@ -65,14 +65,14 @@ class StringifyCallSpec(NamedTuple): ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some"), + spy=SpyInfo(id=42, name="some", is_async=False), payload=SpyPropAccess(prop_name="name", access_type=PropAccessType.GET), ), expected="some.name", ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some"), + spy=SpyInfo(id=42, name="some", is_async=False), payload=SpyPropAccess( prop_name="name", access_type=PropAccessType.SET, @@ -83,7 +83,7 @@ class StringifyCallSpec(NamedTuple): ), StringifyCallSpec( call=SpyEvent( - spy=SpyInfo(id=42, name="some"), + spy=SpyInfo(id=42, name="some", is_async=False), payload=SpyPropAccess(prop_name="name", access_type=PropAccessType.DELETE), ), expected="del some.name", diff --git a/tests/test_stub_store.py b/tests/test_stub_store.py index e1e7f02..a773cc5 100644 --- a/tests/test_stub_store.py +++ b/tests/test_stub_store.py @@ -9,14 +9,16 @@ def test_get_by_call() -> None: """It should be able to add a StubBehavior to the store and get it back.""" subject = StubStore() rehearsal = WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior = StubBehavior(return_value="hello world") subject.add(rehearsal=rehearsal, behavior=behavior) result = subject.get_by_call( call=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) ) @@ -27,11 +29,13 @@ def test_get_by_call_prefers_latest() -> None: """It should be prefer later stubs if multiple exist.""" subject = StubStore() rehearsal_1 = WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior_1 = StubBehavior(return_value="hello") rehearsal_2 = WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior_2 = StubBehavior(return_value="goodbye") @@ -39,7 +43,8 @@ def test_get_by_call_prefers_latest() -> None: subject.add(rehearsal=rehearsal_2, behavior=behavior_2) result = subject.get_by_call( call=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) ) @@ -51,7 +56,8 @@ def test_get_by_call_empty() -> None: subject = StubStore() result = subject.get_by_call( call=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) ) @@ -63,14 +69,14 @@ def test_get_by_call_empty() -> None: [ SpyEvent( # spy_id does not match - spy=SpyInfo(id=1000000000, name="my_spy"), + spy=SpyInfo(id=1000000000, name="my_spy", is_async=False), payload=SpyCall( args=("hello", "world"), kwargs={"goodbye": "so long"}, ), ), SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), # args do not match payload=SpyCall( args=("hello", "wisconsin"), @@ -78,7 +84,7 @@ def test_get_by_call_empty() -> None: ), ), SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall( args=("hello", "wisconsin"), # kwargs do not match @@ -91,7 +97,7 @@ def test_get_by_call_no_match(call: SpyEvent) -> None: """It should return a no-op StubBehavior if there are no matching calls.""" subject = StubStore() rehearsal = WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall( args=("hello", "world"), kwargs={"goodbye": "so long"}, @@ -109,7 +115,8 @@ def test_get_by_call_once_behavior() -> None: """It should consume any behavior marked with the `once` flag.""" subject = StubStore() rehearsal = WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(1, 2, 3), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(1, 2, 3), kwargs={}), ) behavior = StubBehavior(return_value="fizzbuzz", once=True) @@ -117,7 +124,7 @@ def test_get_by_call_once_behavior() -> None: result = subject.get_by_call( call=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ) ) @@ -126,7 +133,7 @@ def test_get_by_call_once_behavior() -> None: result = subject.get_by_call( call=SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ) ) @@ -138,10 +145,12 @@ def test_clear() -> None: """It should consume any behavior marked with the `once` flag.""" subject = StubStore() call = SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) rehearsal = WhenRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ) behavior = StubBehavior(return_value="fizzbuzz") diff --git a/tests/test_unittest.py b/tests/test_unittest.py index ffc389e..04af4ae 100644 --- a/tests/test_unittest.py +++ b/tests/test_unittest.py @@ -2,7 +2,7 @@ import unittest from decoy import Decoy -from .common import SomeClass +from .fixtures import SomeClass class DecoyTestCase(unittest.TestCase): diff --git a/tests/test_verifier.py b/tests/test_verifier.py index aa766aa..7b74b58 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -19,7 +19,8 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], calls=[], @@ -27,16 +28,17 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=42, name="my_spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), ], @@ -44,29 +46,29 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=("oh no",), kwargs={}), ), ], @@ -74,25 +76,25 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), ], @@ -100,17 +102,17 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], @@ -119,17 +121,17 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], @@ -141,13 +143,13 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=42, name="my_spy"), + spy=SpyInfo(id=42, name="my_spy", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], @@ -155,29 +157,29 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], @@ -185,33 +187,33 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(0, 0, 0), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=202, name="spy_202"), + spy=SpyInfo(id=202, name="spy_202", is_async=False), payload=SpyCall(args=(7, 8, 9), kwargs={}), ), ], @@ -219,17 +221,17 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], @@ -238,17 +240,17 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(4, 5, 6), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], @@ -257,7 +259,7 @@ class VerifySpec(NamedTuple): VerifySpec( rehearsals=[ VerifyRehearsal( - spy=SpyInfo(id=101, name="spy_101"), + spy=SpyInfo(id=101, name="spy_101", is_async=False), payload=SpyCall(args=(1, 2, 3), kwargs={}), ), ], diff --git a/tests/test_warning_checker.py b/tests/test_warning_checker.py index 50a3e28..1611447 100644 --- a/tests/test_warning_checker.py +++ b/tests/test_warning_checker.py @@ -34,10 +34,12 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[], @@ -46,7 +48,8 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[], @@ -55,23 +58,25 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ) ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ) ], @@ -82,10 +87,12 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[], @@ -94,19 +101,19 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyPropAccess( prop_name="prop_name", access_type=PropAccessType.GET ), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyPropAccess( prop_name="other_prop", access_type=PropAccessType.GET ), ), WhenRehearsal( - spy=SpyInfo(id=2, name="spy.other_prop"), + spy=SpyInfo(id=2, name="spy.other_prop", is_async=False), payload=SpyCall(args=(), kwargs={}, ignore_extra_args=False), ), ], @@ -116,30 +123,33 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(0,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(0,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(0,), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], @@ -150,26 +160,29 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=2, name="yps"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=2, name="yps", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], @@ -180,26 +193,29 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], @@ -210,29 +226,33 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=2, name="yps"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=2, name="yps", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=2, name="yps"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=2, name="yps", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], @@ -240,13 +260,13 @@ class WarningCheckerSpec(NamedTuple): MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=2, name="yps"), + spy=SpyInfo(id=2, name="yps", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=2, name="yps"), + spy=SpyInfo(id=2, name="yps", is_async=False), payload=SpyCall(args=(), kwargs={}), ), ], @@ -258,36 +278,41 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(3,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(3,), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(2,), kwargs={}), ), ], @@ -295,17 +320,17 @@ class WarningCheckerSpec(NamedTuple): MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(3,), kwargs={}), ), ], @@ -316,13 +341,16 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), ], expected_warnings=[], @@ -331,29 +359,33 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), ], expected_warnings=[ MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(1,), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall(args=(2,), kwargs={}), ), ], @@ -364,16 +396,18 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], expected_warnings=[ RedundantVerifyWarning( rehearsal=VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), + spy=SpyInfo(id=1, name="spy", is_async=False), payload=SpyCall( args=(1,), kwargs={}, @@ -386,10 +420,12 @@ class WarningCheckerSpec(NamedTuple): WarningCheckerSpec( all_calls=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), ], expected_warnings=[], diff --git a/tests/test_warnings.py b/tests/test_warnings.py index 78cc9bf..6823079 100644 --- a/tests/test_warnings.py +++ b/tests/test_warnings.py @@ -19,12 +19,14 @@ class WarningSpec(NamedTuple): warning=MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], ), @@ -42,15 +44,18 @@ class WarningSpec(NamedTuple): warning=MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(0,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(0,), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ], ), @@ -69,15 +74,18 @@ class WarningSpec(NamedTuple): warning=MiscalledStubWarning( rehearsals=[ WhenRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(), kwargs={}), ), ], calls=[ SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), SpyEvent( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(2,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(2,), kwargs={}), ), ], ), @@ -95,7 +103,8 @@ class WarningSpec(NamedTuple): WarningSpec( warning=RedundantVerifyWarning( rehearsal=VerifyRehearsal( - spy=SpyInfo(id=1, name="spy"), payload=SpyCall(args=(1,), kwargs={}) + spy=SpyInfo(id=1, name="spy", is_async=False), + payload=SpyCall(args=(1,), kwargs={}), ), ), expected_message=os.linesep.join(