async def test_merge_streams_concat(): s1: AsyncTestSubject[int] = AsyncTestSubject() s2 = rx.from_iterable([1, 2, 3]) xs = rx.from_iterable([s1, s2]) ys = pipe(xs, rx.merge_inner(1)) obv = AsyncTestObserver() await ys.subscribe_async(obv) await s1.asend_at(1, 10) await s1.asend_at(2, 20) await s1.asend_at(4, 30) await s1.aclose_at(6) await obv assert obv.values == [ (1, OnNext(10)), (2, OnNext(20)), (4, OnNext(30)), (6, OnNext(1)), (6, OnNext(2)), (6, OnNext(3)), (6, OnCompleted), ]
async def test_merge_done(): xs: AsyncTestSubject[AsyncObservable[int]] = AsyncTestSubject() ys = pipe(xs, rx.merge_inner()) obv = AsyncTestObserver() await ys.subscribe_async(obv) await xs.asend(rx.from_iterable([10])) await xs.asend(rx.from_iterable([20])) await xs.aclose() await obv assert obv.values == [(0, OnNext(10)), (0, OnNext(20)), (0, OnCompleted)]
async def test_concat_happy(): xs = rx.from_iterable(range(5)) ys = rx.from_iterable(range(5, 10)) result = [] async def asend(value: int) -> None: result.append(value) zs = pipe(xs, rx.concat(ys)) obv: rx.AsyncObserver[int] = rx.AsyncAwaitableObserver(asend) await rx.run(zs, obv) assert result == list(range(10))
async def test_map_mapper_throws(): error = Exception("ex") exception = None xs = rx.from_iterable([1]) async def athrow(ex: Exception): nonlocal exception exception = ex def mapper(x: int): raise error ys = pipe(xs, rx.map(mapper)) obv = rx.AsyncAwaitableObserver(athrow=athrow) await ys.subscribe_async(obv) try: await obv except Exception as ex: assert exception == ex else: assert False
async def test_pipe_complex_pipe(): xs = rx.from_iterable([1, 2, 3]) result = [] def mapper(value: int) -> int: return value * 10 async def predicate(value: int) -> bool: await asyncio.sleep(0.1) return value > 1 def long_running(value: int) -> AsyncObservable[int]: return rx.from_iterable([value]) ys = pipe( xs, rx.filter_async(predicate), rx.map(mapper), rx.flat_map(long_running), rx.to_async_iterable, ) async for value in ys: result.append(value) assert result == [20, 30]
async def test_async_iteration() -> None: xs = rx.from_iterable([1, 2, 3]) result = [] async for x in rx.to_async_iterable(xs): result.append(x) assert result == [1, 2, 3]
async def test_async_iteration_aync_with() -> None: xs = rx.from_iterable([1, 2, 3]) result = [] obv = rx.AsyncIteratorObserver(xs) async for x in obv: result.append(x) assert result == [1, 2, 3]
async def test_distinct_until_changed_different(): xs = rx.from_iterable([1, 2, 3]) obv: AsyncTestObserver[int] = AsyncTestObserver() ys = pipe(xs, rx.distinct_until_changed) await rx.run(ys, obv) assert obv.values == [(0, OnNext(1)), (0, OnNext(2)), (0, OnNext(3)), (0, OnCompleted)]
async def test_take_normal() -> None: xs = rx.from_iterable([1, 2, 3, 4, 5]) ys = pipe(xs, rx.take(2)) obv: AsyncTestObserver[int] = AsyncTestObserver() result = await rx.run(ys, obv) assert result == 2 assert obv.values == [(0, OnNext(1)), (0, OnNext(2)), (0, OnCompleted)]
async def test_take_zero() -> None: xs = rx.from_iterable([1, 2, 3, 4, 5]) ys = pipe(xs, rx.take(0)) obv: AsyncTestObserver[int] = AsyncTestObserver() with pytest.raises(CancelledError): await rx.run(ys, obv) assert obv.values == [(0, OnCompleted)]
async def test_from_iterable_happy(): xs = rx.from_iterable([1, 2, 3]) obv: AsyncTestObserver[int] = AsyncTestObserver() await rx.run(xs, obv) assert obv.values == [ (0, OnNext(1)), (0, OnNext(2)), (0, OnNext(3)), (0, OnCompleted), ]
async def test_forward_pipe_map() -> None: xs = rx.from_iterable([1, 2, 3]) def mapper(value: int) -> int: return value * 10 ys = pipe(xs, rx.map(mapper)) obv: AsyncTestObserver[int] = AsyncTestObserver() await rx.run(ys, obv) assert obv.values == [(0, OnNext(10)), (0, OnNext(20)), (0, OnNext(30)), (0, OnCompleted)]
async def main(): xs = rx.from_iterable(range(10)) # Split into odds and evens evens = pipe(xs, rx.filter(lambda x: x % 2 == 0)) odds = pipe(xs, rx.filter(lambda x: x % 2 == 1)) async def mysink(value: int): print(value) await odds.subscribe_async(rx.AsyncAnonymousObserver(mysink)) await evens.subscribe_async(rx.AsyncAnonymousObserver(mysink))
async def test_async_iteration_inception() -> None: # iterable to async source to async iterator to async source xs = rx.from_iterable([1, 2, 3]) obv = rx.AsyncIteratorObserver(xs) ys = rx.from_async_iterable(obv) result = [] async for y in rx.to_async_iterable(ys): result.append(y) assert result == [1, 2, 3]
async def test_from_iterable_observer_throws(): xs = rx.from_iterable([1, 2, 3]) error = Exception("error") async def asend(value: int) -> None: raise error obv: AsyncTestObserver[int] = AsyncTestObserver(asend) await xs.subscribe_async(obv) with pytest.raises(Exception): await obv assert obv.values == [(0, OnNext(1)), (0, OnError(error))]
async def main() -> None: xs = rx.from_iterable([1, 2, 3, 4, 5]) async def mapper(value: int) -> rx.AsyncObservable[int]: fut = executor.submit(long_running, value) return rx.of_async(wrap_future(fut)) ys = pipe( xs, rx.flat_map_async(mapper), rx.to_async_iterable, ) async for x in ys: print(x)
async def test_filter_happy() -> None: xs = rx.from_iterable([1, 2, 3]) result = [] async def asend(value: int) -> None: result.append(value) async def predicate(value: int) -> bool: await asyncio.sleep(0.1) return value > 1 ys = pipe(xs, rx.filter_async(predicate)) value = await rx.run(ys, rx.AsyncAwaitableObserver(asend)) assert value == 3 assert result == [2, 3]
async def test_mapi_works(): xs: AsyncObservable[int] = rx.from_iterable([1, 2, 3]) values = [] async def asend(value: int) -> None: values.append(value) def mapper(a: int, i: int) -> int: return a + i ys = pipe(xs, rx.mapi(mapper)) obv: AsyncObserver[int] = rx.AsyncAwaitableObserver(asend) async with await ys.subscribe_async(obv): result = await obv assert result == 5 assert values == [1, 3, 5]
async def test_filter_predicate_throws() -> None: xs = rx.from_iterable([1, 2, 3]) err = MyException("err") result = [] async def asend(value: int) -> None: result.append(value) async def predicate(value: int) -> bool: await asyncio.sleep(0.1) raise err ys = pipe(xs, rx.filter_async(predicate)) with pytest.raises(MyException): await rx.run(ys, rx.AsyncAwaitableObserver(asend)) assert result == []
async def test_pipe_simple_pipe(): xs = rx.from_iterable([1, 2, 3]) def mapper(value: int) -> int: return value * 10 async def predicate(value: int) -> bool: await asyncio.sleep(0.1) return value > 1 ys = pipe(xs, rx.filter_async(predicate), rx.map(mapper)) obv: AsyncTestObserver[int] = AsyncTestObserver() await rx.run(ys, obv) assert obv.values == [ (approx(0.2), OnNext(20)), (approx(0.3), OnNext(30)), (approx(0.3), OnCompleted), ]
async def test_take_negative() -> None: xs = rx.from_iterable([1, 2, 3, 4, 5]) with pytest.raises(ValueError): pipe(xs, rx.take(-1))
def long_running(value: int) -> AsyncObservable[int]: return rx.from_iterable([value])
async def test_async_comprehension() -> None: xs = rx.from_iterable([1, 2, 3]) result = [x async for x in rx.to_async_iterable(xs)] assert result == [1, 2, 3]
def mapper(value: int) -> rx.AsyncObservable[int]: return rx.from_iterable([value])