async def test_flat_map_monad(): m = rx.single(42) def mapper(x: int) -> AsyncObservable[int]: return rx.single(x * 10) a = await rx.run(pipe(m, rx.flat_map(mapper))) b = await rx.run(rx.single(420)) assert a == b
async def search_wikipedia(term: str) -> rx.AsyncObservable[str]: """Search Wikipedia for a given term""" url = "http://en.wikipedia.org/w/api.php" params = {"action": "opensearch", "search": term, "format": "json"} async with aiohttp.ClientSession() as session: async with session.get(url, params=params) as resp: json_response = await resp.text() return rx.single(json_response)
async def test_flat_map_monad_law_right_identity(): # m >>= return is no different than just m. m = rx.single("move on up") def mapper(x: str) -> AsyncObservable[str]: return rx.single(x) a = await rx.run(pipe(m, rx.flat_map(mapper))) b = await rx.run(m) assert a == b
async def test_flat_map_monad_law_left_identity(): # return x >>= f is the same thing as f x x = 3 def f(x: int) -> AsyncObservable[int]: return rx.single(x + 100000) a = await rx.run(pipe(rx.single(x), rx.flat_map(f))) b = await rx.run(f(x)) assert a == b
async def test_unit_observer_throws(): error = Exception("error") xs = rx.single(42) async def asend(value: int) -> None: raise error obv = AsyncTestObserver(asend) await xs.subscribe_async(obv) try: await obv except Exception as ex: assert ex == error assert obv.values == [(0, OnNext(42)), (0, OnError(error))]
async def test_unit_close(): xs = rx.single(42) sub: Optional[AsyncDisposable] = None async def asend(value: int) -> None: assert sub is not None await sub.dispose_async() await asyncio.sleep(0) obv: AsyncTestObserver[int] = AsyncTestObserver(asend) sub = await xs.subscribe_async(obv) await obv assert obv.values == [ (0, OnNext(42)), (0, OnCompleted), ]
async def test_flat_map_monad_law_associativity(): # (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g) m = rx.single(42) def f(x: int) -> AsyncObservable[int]: return rx.single(x + 1000) def g(y: int) -> AsyncObservable[int]: return rx.single(y * 333) def h(x: int) -> AsyncObservable[int]: return pipe(f(x), rx.flat_map(g)) zs = pipe(m, rx.flat_map(f)) a = await rx.run(pipe(zs, rx.flat_map(g))) b = await rx.run(pipe(m, rx.flat_map(h))) assert a == b
def g(y: int) -> AsyncObservable[int]: return rx.single(y * 333)
def f(x: int) -> AsyncObservable[int]: return rx.single(x + 1000)
def mapper(x: str) -> AsyncObservable[str]: return rx.single(x)
def mapper(x: int) -> AsyncObservable[int]: return rx.single(x * 10)
async def test_unit_happy(): xs = rx.single(42) obv: AsyncTestObserver[int] = AsyncTestObserver() await rx.run(xs, obv) assert obv.values == [(0, OnNext(42)), (0, OnCompleted)]