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_stream_happy(): xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject() sink = AsyncTestObserver() await xs.subscribe_async(sink) await xs.asend_later(1, 10) await xs.asend_later(1, 20) await xs.asend_later(1, 30) assert sink.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30))]
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_stream_happy() -> None: xs: AsyncTestSubject[int] = AsyncTestSubject() obv = AsyncTestObserver() await xs.subscribe_async(obv) await xs.asend_later(1, 10) await xs.asend_later(1, 20) await xs.asend_later(1, 30) assert obv.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30))]
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 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_stream_send_after_close(): xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject() sink = AsyncTestObserver() await xs.subscribe_async(sink) await xs.asend_later(1, 10) await xs.asend_later(1, 20) await xs.asend_later(1, 30) await xs.aclose_later(2) await xs.asend_later(1, 40) assert sink.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30)), (5, OnCompleted)]
async def test_stream_send_after_close() -> None: xs: AsyncTestSubject[int] = AsyncTestSubject() obv = AsyncTestObserver() await xs.subscribe_async(obv) await xs.asend_later(1, 10) await xs.asend_later(1, 20) await xs.asend_later(1, 30) await xs.aclose_later(2) await xs.asend_later(1, 40) assert obv.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30)), (5, OnCompleted)]
async def test_stream_cold_send(): xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject() sink = AsyncTestObserver() async def asend(value: int) -> None: await xs.asend(value) asyncio.ensure_future(asend(42)) await asyncio.sleep(10) async with await xs.subscribe_async(sink): await xs.asend_later(1, 20) assert sink.values == [(10, OnNext(42)), (11, OnNext(20))]
async def test_slice_special(): xs = AsyncRx.from_iterable([1, 2, 3, 4, 5]) ys = xs[1:-1] obv: AsyncTestObserver[int] = AsyncTestObserver() result = await rx.run(ys, obv) assert result == 4 assert obv.values == [ (0, OnNext(2)), (0, OnNext(3)), (0, OnNext(4)), (0, OnCompleted), ]
async def test_slice_step(): xs = AsyncRx.from_iterable([1, 2, 3, 4, 5]) ys = xs[::2] obv: AsyncTestObserver[int] = AsyncTestObserver() result = await rx.run(ys, obv) assert result == 5 assert obv.values == [ (0, OnNext(1)), (0, OnNext(3)), (0, OnNext(5)), (0, OnCompleted), ]
async def asend(self, value: TSource): log.debug("AsyncAnonymousObserver:asend(%s)", value) time = self.time() self._values.append((time, OnNext(value))) await self._send(value) await super().asend(value)
async def test_stream_throws(): ex = MyException("ex") xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject() sink = AsyncTestObserver() with pytest.raises(MyException): await xs.subscribe_async(sink) await xs.asend_later(1, 10) await xs.asend_later(1, 20) await xs.asend_later(1, 30) await xs.athrow_later(1, ex) await xs.asend_later(1, 40) await sink assert sink.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30)), (4, OnError(ex))]
async def test_delay_done(): xs: AsyncTestSubject[int] = AsyncTestSubject() ys = pipe(xs, rx.delay(1.0)) obv = AsyncTestObserver() async with await ys.subscribe_async(obv): await xs.asend_later(0, 10) await xs.asend_later(1.0, 20) await xs.aclose_later(1.0) await obv assert obv.values == [ (ca(1), OnNext(10)), (ca(2), OnNext(20)), (ca(3), OnCompleted), ]
async def test_chain_map(): xs = AsyncRx.from_iterable([1, 2, 3]) def mapper(value: int) -> int: return value * 10 ys = xs.map(mapper) obv: AsyncTestObserver[int] = AsyncTestObserver() await ys.subscribe_async(obv) await obv assert obv.values == [ (0, OnNext(10)), (0, OnNext(20)), (0, OnNext(30)), (0, OnCompleted), ]
async def test_flap_map_done(): xs: rx.AsyncSubject[int] = rx.AsyncSubject() def mapper(value: int) -> rx.AsyncObservable[int]: return rx.from_iterable([value]) ys = pipe(xs, rx.flat_map(mapper)) obv = AsyncTestObserver() await ys.subscribe_async(obv) await xs.asend(10) await xs.asend(20) await xs.aclose() await obv assert obv.values == [(0, OnNext(10)), (0, OnNext(20)), (0, OnCompleted)]
async def test_delay_throw(): error = Exception("ex") xs: AsyncTestSubject[int] = AsyncTestSubject() ys = pipe(xs, rx.delay(0.3)) obv = AsyncTestObserver() await ys.subscribe_async(obv) await xs.asend(10) await asyncio.sleep(1) await xs.asend(20) await xs.athrow(error) await asyncio.sleep(1) assert obv.values == [ (ca(0.3), OnNext(10)), (ca(1.3), OnNext(20)), (ca(1.6), OnError(error)), ]
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_unit_happy_resolved_future(): fut: Awaitable[int] = asyncio.Future() xs = rx.from_async(fut) fut.set_result(42) obv: AsyncTestObserver[int] = AsyncTestObserver() await rx.run(xs, obv) assert obv.values == [ (0, OnNext(42)), (0, OnCompleted), ]
async def test_chain_simple_pipe(): xs = AsyncRx.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 = xs.filter_async(predicate).map(mapper) obv: AsyncTestObserver[int] = AsyncTestObserver() await ys.subscribe_async(obv) await obv assert obv.values == [ (ca(0.2), OnNext(20)), (ca(0.3), OnNext(30)), (ca(0.3), OnCompleted), ]
async def test_debounce(): xs: AsyncTestSubject[int] = AsyncTestSubject() ys = pipe(xs, rx.debounce(0.5)) obv: AsyncTestObserver[int] = AsyncTestObserver() await ys.subscribe_async(obv) await xs.asend(1) # 0 -> 0.5 await asyncio.sleep(0.6) # 0.6 await xs.asend(2) # 0.6 -> 1.1 await asyncio.sleep(0.6) # 1.2 await xs.aclose() # 1.2 await asyncio.sleep(0.6) await obv assert obv.values == [ (ca(0.5), OnNext(1)), (ca(1.1), OnNext(2)), (ca(1.2), OnCompleted), ]
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_streams(): xs: AsyncTestSubject[AsyncObservable[int]] = AsyncTestSubject() s1: AsyncTestSubject[int] = AsyncTestSubject() s2: AsyncTestSubject[int] = AsyncTestSubject() ys = pipe(xs, rx.merge_inner()) obv = AsyncTestObserver() await ys.subscribe_async(obv) await xs.asend(s1) await xs.asend(s2) await s1.asend_at(1, 10) await s1.asend_at(2, 20) await s1.asend_at(4, 30) await s1.aclose_at(6) await s2.asend_at(0, 40) await s2.asend_at(3, 50) await s2.asend_at(5, 60) await s2.aclose_at(6) await xs.aclose() await obv assert obv.values == [ (0, OnNext(40)), (1, OnNext(10)), (2, OnNext(20)), (3, OnNext(50)), (4, OnNext(30)), (5, OnNext(60)), (6, OnCompleted), ]
async def test_unit_happy_future_resolve(): fut: Awaitable[int] = asyncio.Future() xs = rx.from_async(fut) obv: AsyncTestObserver[int] = AsyncTestObserver() async with await xs.subscribe_async(obv): fut.set_result(42) await obv assert obv.values == [ (0, OnNext(42)), (0, OnCompleted), ]
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 test_delay_cancel_before_done(): xs: AsyncTestSubject[int] = AsyncTestSubject() ys = pipe(xs, rx.delay(0.3)) obv = AsyncTestObserver() async with await ys.subscribe_async(obv): await xs.asend(10) await asyncio.sleep(1.5) await xs.asend(20) await asyncio.sleep(1) assert obv.values == [ (ca(0.3), OnNext(10)), ]
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_withlatestfrom_done(): xs: AsyncTestSubject[int] = AsyncTestSubject() ys: AsyncTestSubject[int] = AsyncTestSubject() zs = pipe(xs, rx.with_latest_from(ys), rx.starmap(lambda x, y: x + y)) obv: AsyncTestObserver[int] = AsyncTestObserver() async with await zs.subscribe_async(obv): await xs.asend(1) await ys.asend(2) await xs.asend(3) await xs.aclose() await obv assert obv.values == [(0, OnNext(5)), (0, OnCompleted)]
async def test_stream_cancel() -> None: xs: AsyncTestSubject[int] = AsyncTestSubject() subscription: Optional[AsyncDisposable] = None def mapper(value: int) -> int: return value * 10 ys = pipe(xs, rx.map(mapper)) obv = AsyncTestObserver() subscription = await ys.subscribe_async(obv) await xs.asend_later(1, 10) await subscription.dispose_async() await xs.asend_later(1, 20) assert obv.values == [(1, OnNext(100))]