venv added, updated
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
from typing import Any, Callable, List, Optional, TypeVar, Union, cast
|
||||
|
||||
import reactivex
|
||||
from reactivex import Observable, abc, typing
|
||||
from reactivex.disposable import Disposable
|
||||
from reactivex.scheduler import VirtualTimeScheduler
|
||||
from reactivex.testing.recorded import Recorded
|
||||
|
||||
from .coldobservable import ColdObservable
|
||||
from .hotobservable import HotObservable
|
||||
from .mockobserver import MockObserver
|
||||
from .reactivetest import ReactiveTest
|
||||
|
||||
_T = TypeVar("_T")
|
||||
_TState = TypeVar("_TState")
|
||||
|
||||
|
||||
class TestScheduler(VirtualTimeScheduler):
|
||||
"""Test time scheduler used for testing applications and libraries
|
||||
built using Reactive Extensions. All time, both absolute and relative is
|
||||
specified as integer ticks"""
|
||||
|
||||
__test__ = False
|
||||
|
||||
def schedule_absolute(
|
||||
self,
|
||||
duetime: typing.AbsoluteTime,
|
||||
action: typing.ScheduledAction[_TState],
|
||||
state: _TState = None,
|
||||
) -> abc.DisposableBase:
|
||||
"""Schedules an action to be executed at the specified virtual
|
||||
time.
|
||||
|
||||
Args:
|
||||
duetime: Absolute virtual time at which to execute the
|
||||
action.
|
||||
action: Action to be executed.
|
||||
state: State passed to the action to be executed.
|
||||
|
||||
Returns:
|
||||
Disposable object used to cancel the scheduled action
|
||||
(best effort).
|
||||
"""
|
||||
|
||||
duetime = duetime if isinstance(duetime, float) else self.to_seconds(duetime)
|
||||
return super().schedule_absolute(duetime, action, state)
|
||||
|
||||
def start(
|
||||
self,
|
||||
create: Optional[Callable[[], Observable[_T]]] = None,
|
||||
created: Optional[float] = None,
|
||||
subscribed: Optional[float] = None,
|
||||
disposed: Optional[float] = None,
|
||||
) -> MockObserver[_T]:
|
||||
"""Starts the test scheduler and uses the specified virtual
|
||||
times to invoke the factory function, subscribe to the
|
||||
resulting sequence, and dispose the subscription.
|
||||
|
||||
Args:
|
||||
create: Factory method to create an observable sequence.
|
||||
created: Virtual time at which to invoke the factory to
|
||||
create an observable sequence.
|
||||
subscribed: Virtual time at which to subscribe to the
|
||||
created observable sequence.
|
||||
disposed: Virtual time at which to dispose the
|
||||
subscription.
|
||||
|
||||
Returns:
|
||||
Observer with timestamped recordings of notification
|
||||
messages that were received during the virtual time window
|
||||
when the subscription to the source sequence was active.
|
||||
"""
|
||||
|
||||
# Defaults
|
||||
created = created or ReactiveTest.created
|
||||
subscribed = subscribed or ReactiveTest.subscribed
|
||||
disposed = disposed or ReactiveTest.disposed
|
||||
|
||||
observer = self.create_observer()
|
||||
subscription: Optional[abc.DisposableBase] = None
|
||||
source: Optional[abc.ObservableBase[_T]] = None
|
||||
|
||||
def action_create(
|
||||
scheduler: abc.SchedulerBase, state: Any = None
|
||||
) -> abc.DisposableBase:
|
||||
"""Called at create time. Defaults to 100"""
|
||||
nonlocal source
|
||||
source = create() if create is not None else reactivex.never()
|
||||
return Disposable()
|
||||
|
||||
self.schedule_absolute(created, action_create)
|
||||
|
||||
def action_subscribe(
|
||||
scheduler: abc.SchedulerBase, state: Any = None
|
||||
) -> abc.DisposableBase:
|
||||
"""Called at subscribe time. Defaults to 200"""
|
||||
nonlocal subscription
|
||||
if source:
|
||||
subscription = source.subscribe(observer, scheduler=scheduler)
|
||||
return Disposable()
|
||||
|
||||
self.schedule_absolute(subscribed, action_subscribe)
|
||||
|
||||
def action_dispose(
|
||||
scheduler: abc.SchedulerBase, state: Any = None
|
||||
) -> abc.DisposableBase:
|
||||
"""Called at dispose time. Defaults to 1000"""
|
||||
if subscription:
|
||||
subscription.dispose()
|
||||
return Disposable()
|
||||
|
||||
self.schedule_absolute(disposed, action_dispose)
|
||||
|
||||
super().start()
|
||||
return observer
|
||||
|
||||
def create_hot_observable(
|
||||
self, *args: Union[Recorded[_T], List[Recorded[_T]]]
|
||||
) -> HotObservable[_T]:
|
||||
"""Creates a hot observable using the specified timestamped
|
||||
notification messages either as a list or by multiple arguments.
|
||||
|
||||
Args:
|
||||
messages: Notifications to surface through the created sequence at
|
||||
their specified absolute virtual times.
|
||||
|
||||
Returns hot observable sequence that can be used to assert the timing
|
||||
of subscriptions and notifications.
|
||||
"""
|
||||
|
||||
if args and isinstance(args[0], List):
|
||||
messages = args[0]
|
||||
else:
|
||||
messages = cast(List[Recorded[_T]], list(args))
|
||||
return HotObservable(self, messages)
|
||||
|
||||
def create_cold_observable(
|
||||
self, *args: Union[Recorded[_T], List[Recorded[_T]]]
|
||||
) -> ColdObservable[_T]:
|
||||
"""Creates a cold observable using the specified timestamped
|
||||
notification messages either as an array or arguments.
|
||||
|
||||
Args:
|
||||
args: Notifications to surface through the created sequence
|
||||
at their specified virtual time offsets from the
|
||||
sequence subscription time.
|
||||
|
||||
Returns:
|
||||
Cold observable sequence that can be used to assert the
|
||||
timing of subscriptions and notifications.
|
||||
"""
|
||||
|
||||
if args and isinstance(args[0], list):
|
||||
messages = args[0]
|
||||
else:
|
||||
messages = cast(List[Recorded[_T]], list(args))
|
||||
return ColdObservable(self, messages)
|
||||
|
||||
def create_observer(self) -> MockObserver[Any]:
|
||||
"""Creates an observer that records received notification messages and
|
||||
timestamps those. Return an Observer that can be used to assert the
|
||||
timing of received notifications.
|
||||
"""
|
||||
|
||||
return MockObserver(self)
|
||||
Reference in New Issue
Block a user