Beispiel #1
0
class TestFromIterable(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()
        self.subscriber = init_subscriber(
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
        )

    def test_base(self):
        test_list = [1, 2, 3]
        base = ObjectRefBase("test")

        subscription = rxbp.from_iterable(test_list).unsafe_subscribe(
            self.subscriber)

        self.assertEqual(base, subscription.info.base)

    def test_from_list(self):
        test_list = [1, 2, 3]

        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_iterable(test_list).unsafe_subscribe(
            Subscriber(scheduler=self.scheduler,
                       subscribe_scheduler=self.scheduler))
        subscription.observable.observe(init_observer_info(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual(test_list, sink.received)
class TestEmptySource(unittest.TestCase):
    def setUp(self) -> None:
        self.multicast_scheduler = TScheduler()
        self.source_scheduler = TScheduler()
        self.info = MultiCastInfo(
            multicast_scheduler=self.multicast_scheduler,
            source_scheduler=self.source_scheduler,
        )
        self.o = MockObserver(self.source_scheduler)

    def test_initialize(self):
        rxbp.multicast.empty()

    def test_send_item_on_subscribe_scheduler(self):
        mc = rxbp.multicast.empty()

        source = mc.get_source(self.info)
        source.subscribe(self.o)

        self.assertEqual(0, len(self.o.messages))

        self.multicast_scheduler.advance_by(1)

        assert self.o.messages == [
            on_completed(0),
        ]
Beispiel #3
0
class TestFromRange(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()

    def test_base(self):
        subscription = rxbp.from_range(1, 4).unsafe_subscribe(
            Subscriber(scheduler=self.scheduler,
                       subscribe_scheduler=self.scheduler))

        self.assertEqual(NumericalBase(3), subscription.info.base)

    def test_use_case(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_range(1, 4).unsafe_subscribe(
            Subscriber(scheduler=self.scheduler,
                       subscribe_scheduler=self.scheduler))
        subscription.observable.observe(ObserverInfo(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3], sink.received)
        self.assertTrue(sink.is_completed)

    def test_from_list_batch_size_of_one(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_range(1, 4, batch_size=1).unsafe_subscribe(
            Subscriber(scheduler=self.scheduler,
                       subscribe_scheduler=self.scheduler))
        subscription.observable.observe(ObserverInfo(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual([1], sink.received)
        self.assertFalse(sink.is_completed)

        sink.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], sink.received)

    def test_from_list_batch_size_of_two(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_range(1, 4, batch_size=2).unsafe_subscribe(
            Subscriber(scheduler=self.scheduler,
                       subscribe_scheduler=self.scheduler))
        subscription.observable.observe(ObserverInfo(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], sink.received)

        sink.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3], sink.received)
        self.assertTrue(sink.is_completed)
class TestFromList(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()
        self.subscriber = init_subscriber(
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
        )

    def test_from_list(self):
        test_list = [1, 2, 3]

        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_list(test_list).unsafe_subscribe(
            self.subscriber)
        subscription.observable.observe(init_observer_info(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual(test_list, sink.received)
        self.assertTrue(sink.is_completed)

    def test_from_list_batch_size_of_one(self):
        test_list = [1, 2, 3]

        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_list(
            test_list, batch_size=1).unsafe_subscribe(self.subscriber)
        subscription.observable.observe(init_observer_info(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual(test_list[:1], sink.received)
        self.assertFalse(sink.is_completed)

        sink.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual(test_list[:2], sink.received)

    def test_from_list_batch_size_of_two(self):
        test_list = [1, 2, 3]

        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_list(
            test_list, batch_size=2).unsafe_subscribe(self.subscriber)
        subscription.observable.observe(init_observer_info(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual(test_list[:2], sink.received)

        sink.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual(test_list, sink.received)
        self.assertTrue(sink.is_completed)
Beispiel #5
0
class TestLoopFlowablesMultiCast(unittest.TestCase):
    def setUp(self) -> None:
        self.multicast_scheduler = TScheduler()
        self.source_scheduler = TScheduler()
        self.info = MultiCastInfo(
            multicast_scheduler=self.multicast_scheduler,
            source_scheduler=self.source_scheduler,
        )
        self.source_multicast = TestMultiCast()
        self.rx_sink = TestMultiCastObserver()
        self.source1 = TestFlowable()
        self.source2 = TestFlowable()

    def test_send_single_flowable(self):
        reduce_multicast = LoopFlowableMultiCast(
            source=self.source_multicast,
            func=lambda m: MultiCast(m).pipe(
                rxbp.multicast.op.map(lambda t: t[0]), ),
            initial=[0],
        )
        reduce_multicast.get_source(self.info).subscribe(self.rx_sink)

        self.source_multicast.on_next(Flowable(self.source1))

        self.assertEqual(1, len(self.rx_sink.received))

    def test_subscribe_single_flowable(self):
        reduce_multicast = LoopFlowableMultiCast(
            source=self.source_multicast,
            func=lambda m: MultiCast(m).pipe(
                rxbp.multicast.op.map(lambda t: t[0]), ),
            initial=[10],
        )
        reduce_multicast.get_source(self.info).subscribe(self.rx_sink)
        self.source_multicast.on_next(Flowable(self.source1))

        sink = TObserver(immediate_continue=0)
        subscription = self.rx_sink.received[0].unsafe_subscribe(
            Subscriber(
                scheduler=self.source_scheduler,
                subscribe_scheduler=self.source_scheduler,
            ))
        subscription.observable.observe(init_observer_info(sink))

        self.multicast_scheduler.advance_by(1)
        self.source_scheduler.advance_by(1)

        # self.source1.on_next_single(0)

        print(sink.received)

        self.assertEqual([10], sink.received)
class TestReturnValue(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()
        self.subscriber = init_subscriber(
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
        )

    def test_use_case(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.return_value(1).unsafe_subscribe(self.subscriber)
        subscription.observable.observe(init_observer_info(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual([1], sink.received)
Beispiel #7
0
class TestFromRange(unittest.TestCase):
    def setUp(self):
        self.scheduler = TScheduler()

    def test_happy_case(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.empty().unsafe_subscribe(
            Subscriber(
                scheduler=self.scheduler,
                subscribe_scheduler=self.scheduler,
            ))
        disposable = subscription.observable.observe(
            init_observer_info(observer=sink))

        self.scheduler.advance_by(1)

        self.assertEqual([], sink.received)
        self.assertTrue(sink.is_completed)
class TestZip(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()
        self.sources = [TestFlowable(), TestFlowable(), TestFlowable()]

    def test_use_case(self):
        sink = TObserver()
        subscription = rxbp.merge(
            *[Flowable(e) for e in self.sources]).unsafe_subscribe(
                Subscriber(scheduler=self.scheduler,
                           subscribe_scheduler=self.scheduler))
        subscription.observable.observe(init_observer_info(observer=sink))

        self.sources[0].observable.on_next_single(1)
        self.sources[1].observable.on_next_single(2)
        self.sources[2].observable.on_next_single(3)

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3], sink.received)
class TestEvictingBufferedObserver(TestCaseBase):
    def setUp(self):
        self.scheduler = TScheduler()
        self.sink = TObserver(immediate_continue=0)

    def test_should_block_onnext_until_connected(self):
        s: TScheduler = self.scheduler

        strategy = DropOld(4)
        evicting_obs = EvictingBufferedObserver(self.sink,
                                                scheduler=s,
                                                strategy=strategy,
                                                subscribe_scheduler=s)
        s1 = TObservable(observer=evicting_obs)

        s1.on_next_single(1)
        s1.on_next_single(2)
        ack = s1.on_next_single(3)
        self.assertIsInstance(ack, ContinueAck)

        ack = s1.on_next_single(4)
        self.assertIsInstance(ack, ContinueAck)

        ack = s1.on_next_single(5)
        self.assertIsInstance(ack, ContinueAck)

        self.assertEqual(len(self.sink.received), 0)

        self.scheduler.advance_by(1)

        self.assertEqual([2], self.sink.received)

        self.sink.ack.on_next(continue_ack)

        self.scheduler.advance_by(1)

        self.assertEqual(self.sink.received, [2, 3])
Beispiel #10
0
class TestFromRange(unittest.TestCase):
    def setUp(self):
        self.scheduler = TScheduler()

    def test_happy_case(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_range(1, 4).unsafe_subscribe(Subscriber(
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
        ))
        disposable = subscription.observable.observe(ObserverInfo(
            observer=sink
        ))

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3], sink.received)
        self.assertTrue(sink.is_completed)

    def test_batch_size(self):
        sink = TObserver(immediate_continue=0)
        subscription = rxbp.from_range(1, 4, batch_size=2).unsafe_subscribe(Subscriber(
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
        ))
        disposable = subscription.observable.observe(ObserverInfo(
            observer=sink
        ))

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], sink.received)
        self.assertFalse(sink.is_completed)

        sink.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3], sink.received)
        self.assertTrue(sink.is_completed)
Beispiel #11
0
class TestImperativeMultiCastBuilder(unittest.TestCase):
    def setUp(self) -> None:
        self.source = TestFlowable()
        self.scheduler = TScheduler()
        self.composite_disposable = CompositeDisposable()
        self.sink1 = TObserver()
        self.sink2 = TObserver()
        self.sink3 = TObserver()

    def test_common_case(self):
        s1 = [None]
        s2 = [None]
        s3 = [None]

        def func(builder: ImperativeMultiCastBuilder):
            builder = ImperativeMultiCastBuilder(
                source_scheduler=self.scheduler,
                composite_disposable=self.composite_disposable,
            )

            s1[0] = builder.create_multicast_subject()
            s2[0] = builder.create_flowable_subject()
            s3[0] = builder.create_flowable_subject()

            # s1[0].to_flowable().subscribe(observer=self.sink1, scheduler=self.scheduler)
            s2[0].subscribe(observer=self.sink2, scheduler=self.scheduler)

            blocking_flowable = Flowable(self.source)

            def output_selector(flowable: Flowable):
                return rxbp.multicast.return_flowable(flowable)

            return builder.return_(
                blocking_flowable=blocking_flowable,
                output_selector=output_selector,
            )

        rxbp.multicast.build_imperative_multicast(
            func=func, ).to_flowable().subscribe(observer=self.sink3,
                                                 scheduler=self.scheduler)

        self.scheduler.advance_by(1)

        s2[0].on_next(1)
        self.assertEqual([1], self.sink2.received)

        s1[0].on_next(s3[0])
        s3[0].on_next(10)
        self.assertEqual([1], self.sink2.received)

        self.source.on_next_single(20)
        self.assertEqual([20], self.sink3.received)

        # self.assertFalse(self.sink1.is_completed)
        self.assertFalse(self.sink2.is_completed)
        self.assertFalse(self.sink3.is_completed)

        self.source.on_completed()

        # self.assertTrue(self.sink1.is_completed)
        self.assertTrue(self.sink2.is_completed)
        self.assertTrue(self.sink3.is_completed)
Beispiel #12
0
class TestPublishSubject(unittest.TestCase):
    def setUp(self):
        self.scheduler = TScheduler()
        self.exception = Exception()

    def test_should_emit_from_the_point_of_subscription_forward(self):
        subject = PublishObservableSubject(scheduler=self.scheduler)
        s1 = TObservable(observer=subject)

        self.assertIsInstance(s1.on_next_iter([1]), ContinueAck)
        self.assertIsInstance(s1.on_next_iter([2]), ContinueAck)
        self.assertIsInstance(s1.on_next_iter([3]), ContinueAck)

        o1 = TObserver()
        o1.immediate_continue = 5

        subject.observe(init_observer_info(o1))

        self.assertIsInstance(s1.on_next_iter([4]), ContinueAck)
        self.assertIsInstance(s1.on_next_iter([5]), ContinueAck)
        self.assertIsInstance(s1.on_next_iter([6]), ContinueAck)
        s1.on_completed()

        self.assertEqual(sum(o1.received), 15)
        self.assertTrue(o1.is_completed)

    def test_should_work_synchronously_for_synchronous_subscribers(self):
        subject = PublishObservableSubject(self.scheduler)
        s1 = TObservable(observer=subject)

        def gen_observers():
            for i in range(10):
                o1 = TObserver()
                o1.immediate_continue = 5
                subject.observe(init_observer_info(o1))
                yield o1

        obs_list = list(gen_observers())

        self.assertIsInstance(s1.on_next_iter([1]), ContinueAck)
        self.assertIsInstance(s1.on_next_iter([2]), ContinueAck)
        self.assertIsInstance(s1.on_next_iter([3]), ContinueAck)
        s1.on_completed()

        self.assertEqual(sum(sum(o.received) for o in obs_list), 60)
        self.assertTrue(all(o.is_completed for o in obs_list))

    # def test_should_work_with_asynchronous_subscribers(self):
    #     subject = PublishOSubject(self.scheduler)
    #     s1 = TestObservable(observer=subject)
    #
    #     def gen_observers():
    #         for i in range(10):
    #             o1 = TestObserver()
    #             subject.observe(ObserverInfo(o1))
    #             yield o1
    #
    #     obs_list = list(gen_observers())
    #
    #     for i in range(10):
    #         ack = s1.on_next_iter([i])
    #         self.assertFalse(ack.has_value)
    #
    #         for o in obs_list:
    #             o.ack.on_next(continue_ack)
    #
    #         self.assertTrue(ack.has_value)
    #         # todo: e+1??
    #         self.assertEqual(sum(sum(o.received) for o in obs_list), sum(e+1 for e in range(i)) * 10)
    #
    #     subject.on_completed()
    #     self.assertTrue(all(o.is_completed for o in obs_list))

    def test_subscribe_after_complete_should_complete_immediately(self):
        subject = PublishObservableSubject(self.scheduler)
        subject.on_completed()

        o1 = TObserver()
        subject.observe(init_observer_info(o1))
        self.assertTrue(o1.is_completed)

    def test_on_error_should_terminate_current_and_future_subscribers(self):
        subject = PublishObservableSubject(self.scheduler)
        s1 = TObservable(observer=subject)

        def gen_observers():
            for _ in range(10):
                observer = TObserver()
                subject.observe(init_observer_info(observer=observer, ))
                yield observer

        observer_list = list(gen_observers())

        s1.on_next_iter([1])
        s1.on_error(self.exception)

        o1 = TObserver()
        subject.observe(init_observer_info(o1))

        for observer in observer_list:
            self.assertListEqual(observer.received, [1])
            self.assertEqual(observer.exception, self.exception)

        self.assertEqual(o1.exception, self.exception)

    def test_unsubscribe_after_on_complete(self):
        subject = PublishObservableSubject(self.scheduler)
        s1 = TObservable(observer=subject)
        o1 = TObserver()
        d = subject.observe(init_observer_info(o1))

        s1.on_next_iter([1])
        s1.on_completed()

        self.scheduler.advance_by(1)
        d.dispose()
        self.assertListEqual(o1.received, [1])
class TestCollectFlowablesMultiCast(unittest.TestCase):
    def setUp(self) -> None:
        self.multicast_scheduler = TScheduler()
        self.source_scheduler = TScheduler()
        self.info = MultiCastInfo(
            multicast_scheduler=self.multicast_scheduler,
            source_scheduler=self.source_scheduler,
        )
        self.source_multicast = TestMultiCast()
        self.rx_sink = TestMultiCastObserver()
        self.source1 = TestFlowable()
        self.source2 = TestFlowable()

    def test_send_single_flowable(self):
        reduce_multicast = CollectFlowablesMultiCast(source=self.source_multicast)
        reduce_multicast.get_source(self.info).subscribe(self.rx_sink)

        self.source_multicast.on_next(Flowable(self.source1))

        self.assertEqual(1, len(self.rx_sink.received))

    def test_send_dictionary(self):
        reduce_multicast = CollectFlowablesMultiCast(source=self.source_multicast)
        reduce_multicast.get_source(self.info).subscribe(self.rx_sink)

        self.source_multicast.on_next({'f1': Flowable(self.source1)})

        self.assertEqual(1, len(self.rx_sink.received))

    def test_reduce_single_flowables_without_maintaining_order(self):
        rcollected_multicast = CollectFlowablesMultiCast(
            source=self.source_multicast,
            maintain_order=False,
        )
        rcollected_multicast.get_source(self.info).subscribe(self.rx_sink)

        # send two Flowables to check maintain_order property
        self.source_multicast.on_next(Flowable(self.source1))
        self.source_multicast.on_next(Flowable(self.source2))
        self.source_multicast.on_completed()

        sink = TObserver()
        subscription = self.rx_sink.received[0].unsafe_subscribe(Subscriber(
            scheduler=self.source_scheduler,
            subscribe_scheduler=self.source_scheduler
        ))
        subscription.observable.observe(init_observer_info(observer=sink))

        # sending the lifted flowable is scheduled on the multicast_scheduler
        self.multicast_scheduler.advance_by(1)
        self.source_scheduler.advance_by(1)

        self.source1.on_next_single(1)
        self.source2.on_next_single('a')
        self.source1.on_next_single(2)
        self.source1.on_completed()
        self.source2.on_next_single('b')
        self.source2.on_completed()

        self.assertEqual([1, 'a', 2, 'b'], sink.received)
        self.assertTrue(sink.is_completed)

    def test_reduce_single_flowables_with_maintaining_order(self):
        reduce_multicast = CollectFlowablesMultiCast(
            source=self.source_multicast,
            maintain_order=True,
        )
        reduce_multicast.get_source(self.info).subscribe(self.rx_sink)
        self.source_multicast.on_next(Flowable(self.source1))
        self.source_multicast.on_next(Flowable(self.source2))
        self.source_multicast.on_completed()

        sink = TObserver()
        subscription = self.rx_sink.received[0].unsafe_subscribe(Subscriber(
            scheduler=self.source_scheduler,
            subscribe_scheduler=self.source_scheduler
        ))
        subscription.observable.observe(init_observer_info(observer=sink))

        # sending the lifted flowable is scheduled on the multicast_scheduler
        self.multicast_scheduler.advance_by(1)
        self.source_scheduler.advance_by(1)

        self.source1.on_next_single(1)
        self.source2.on_next_single('a')
        self.source1.on_next_single(2)
        self.source1.on_completed()
        self.source2.on_next_single('b')
        self.source2.on_completed()

        self.assertEqual([1, 2, 'a', 'b'], sink.received)
        self.assertTrue(sink.is_completed)
class TestFlatMapObserver(unittest.TestCase):
    def setUp(self):
        self.source = TObservable()
        self.inner_source_1 = TObservable()
        self.inner_source_2 = TObservable()

        self.sink = TObserver()
        self.scheduler = TScheduler()
        self.composite_disposable = CompositeDisposable()
        self.exc = Exception()
        self.lock = threading.RLock()

    def test_initialize(self):
        observer = FlatMapObserver(
            composite_disposable=self.composite_disposable,
            func=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            observer_info=init_observer_info(observer=self.sink),
        )

    def test_backpressure_on_outer_observer(self):
        observer = FlatMapObserver(
            composite_disposable=self.composite_disposable,
            func=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            observer_info=init_observer_info(observer=self.sink),
        )
        self.source.observe(init_observer_info(observer))

        ack1 = self.source.on_next_single(self.inner_source_1)
        self.scheduler.advance_by(1)

        self.assertFalse(ack1.is_sync)

    def test_send_element_on_inner_observer(self):
        observer = FlatMapObserver(
            composite_disposable=self.composite_disposable,
            func=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            observer_info=init_observer_info(observer=self.sink),
        )
        self.source.observe(init_observer_info(observer))
        self.source.on_next_single(self.inner_source_1)
        self.scheduler.advance_by(1)

        ack2 = self.inner_source_1.on_next_iter([1, 2])

        self.assertIsInstance(ack2, ContinueAck)
        self.assertListEqual(self.sink.received, [1, 2])

    def test_release_backpressure_on_completed(self):
        observer = FlatMapObserver(
            composite_disposable=self.composite_disposable,
            func=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            observer_info=init_observer_info(observer=self.sink),
        )
        self.source.observe(init_observer_info(observer))

        ack1 = self.source.on_next_single(self.inner_source_1)
        self.scheduler.advance_by(1)

        self.inner_source_1.on_completed()

        self.assertIsInstance(ack1.value, ContinueAck)

    def test_multiple_inner_observers(self):
        observer = FlatMapObserver(
            composite_disposable=self.composite_disposable,
            func=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            observer_info=init_observer_info(observer=self.sink),
        )
        self.source.observe(init_observer_info(observer))

        self.source.on_next_list([self.inner_source_1, self.inner_source_2])
        self.scheduler.advance_by(1)

        ack1 = self.inner_source_2.on_next_iter([1, 2])
        self.inner_source_2.on_completed()
        ack2 = self.inner_source_1.on_next_iter([3, 4])

        self.assertFalse(ack1.is_sync)
        self.assertIsInstance(ack2, ContinueAck)
        self.assertFalse(self.sink.is_completed)

    def test_multiple_inner_observers_complete(self):
        observer = FlatMapObserver(
            composite_disposable=self.composite_disposable,
            func=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            observer_info=init_observer_info(observer=self.sink),
        )
        self.source.observe(init_observer_info(observer))

        self.source.on_next_list([self.inner_source_1, self.inner_source_2])
        self.source.on_completed()
        self.scheduler.advance_by(1)

        ack1 = self.inner_source_2.on_next_iter([1, 2])
        self.inner_source_2.on_completed()
        ack2 = self.inner_source_1.on_next_iter([3, 4])
        self.inner_source_1.on_completed()

        self.assertListEqual(self.sink.received, [3, 4, 1, 2])
        self.assertTrue(self.sink.is_completed)
class TestFlatConcatNoBackpressureObserver(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()
        self.source = TObservable()

        self.source1 = TObservable()
        self.source2 = TObservable()
        self.source3 = TObservable()

        self.composite_disposable = CompositeDisposable()

    def test_initialize(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))

    def test_on_next_does_not_backpressure(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))

        ack1 = self.source.on_next_single(self.source1)
        ack2 = self.source.on_next_single(self.source2)

        self.assertIsInstance(ack1, ContinueAck)
        self.assertIsInstance(ack2, ContinueAck)

    def test_inner_on_next(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))
        self.source.on_next_single(self.source1)
        self.scheduler.advance_by(1)

        self.source1.on_next_single(1)

        self.assertEqual([1], sink.received)

    def test_on_next_on_second_source(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))
        self.source.on_next_single(self.source1)
        self.scheduler.advance_by(1)
        self.source1.on_next_single(1)
        self.source.on_next_single(self.source2)
        self.scheduler.advance_by(1)

        self.source2.on_next_single('a')

        self.assertEqual([1], sink.received)

    def test_complete_first_source(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))
        self.source.on_next_single(self.source1)
        self.scheduler.advance_by(1)
        self.source1.on_next_single(1)
        self.source.on_next_single(self.source2)
        self.scheduler.advance_by(1)
        self.source.on_completed()
        self.source2.on_next_single('a')

        self.source1.on_completed()

        self.assertEqual([1, 'a'], sink.received)
        self.assertFalse(sink.is_completed)

    def test_complete_first_source2(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))
        self.source.on_next_single(self.source1)
        self.scheduler.advance_by(1)
        self.source1.on_next_single(1)
        self.source.on_next_single(self.source2)
        self.scheduler.advance_by(1)
        self.source.on_completed()
        self.source2.on_next_single('a')
        self.source1.on_next_single(2)
        self.source1.on_completed()
        self.source2.on_next_single('b')

        self.source2.on_completed()

        self.assertEqual([1, 2, 'a', 'b'], sink.received)
        self.assertTrue(sink.is_completed)

    def test_three_sources(self):
        sink = TObserver()
        observer = FlatConcatNoBackpressureObserver(
            next_observer=sink,
            selector=lambda v: v,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            composite_disposable=self.composite_disposable,
        )
        self.source.observe(init_observer_info(observer=observer))
        self.source.on_next_single(self.source1)
        self.source.on_next_single(self.source2)
        self.source.on_next_single(self.source3)
        self.scheduler.advance_by(1)

        self.source1.on_next_single(1)
        self.source2.on_next_single(2)
        self.source3.on_next_single(3)
        self.source1.on_completed()
        self.source2.on_completed()
        self.source3.on_completed()

        self.assertEqual([1, 2, 3], sink.received)
Beispiel #16
0
class TestLiftObservable(unittest.TestCase):
    def setUp(self):
        self.source = TestMultiCastObservable()
        self.sink = TestMultiCastObserver()
        self.scheduler = TScheduler()

        def func(obs: rx.typing.Observable, first):
            return obs

        self.disposable = LiftObservable(
            self.source,
            func=func,
            scheduler=self.scheduler,
        ).pipe(rxop.flat_map(lambda s: s)).subscribe(self.sink)

    def test_scheduled_on_next(self):
        self.source.on_next(1)
        self.source.on_next(2)

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], self.sink.received)
        self.assertFalse(self.sink.is_completed)

    def test_non_scheduled_on_next(self):
        self.source.on_next(1)
        self.source.on_next(2)
        self.scheduler.advance_by(1)

        self.source.on_next(3)
        self.source.on_next(4)

        self.assertEqual([1, 2, 3, 4], self.sink.received)
        self.assertFalse(self.sink.is_completed)

    def test_on_completed(self):
        self.source.on_completed()

        self.assertTrue(self.source.is_disposed)
        self.assertTrue(self.sink.is_completed)

    def test_on_completed_after_on_next(self):
        self.source.on_next(1)
        self.source.on_next(2)
        self.source.on_completed()

        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], self.sink.received)
        self.assertTrue(self.sink.is_completed)

    # def test_dispose(self):
    #     self.source.on_next(1)
    #     self.source.on_next(2)
    #
    #     self.disposable.dispose()
    #
    #     self.assertEqual([], self.sink.received)
    #     self.assertTrue(self.source.is_disposed)

    def test_dispose_without_subscriber(self):
        self.disposable.dispose()

        self.assertTrue(self.source.is_disposed)
class TestCachedServeFirstSubject(TestCaseBase):
    def setUp(self):
        self.scheduler = TScheduler()
        self.source = TObservable()
        self.subject = CacheServeFirstObservableSubject(
            scheduler=self.scheduler)
        self.source.observe(init_observer_info(self.subject))
        self.exc = Exception()

    def test_initialize(self):
        CacheServeFirstObservableSubject(scheduler=self.scheduler)

    def test_on_next_synchronously(self):
        """
                                     on_next
        inactive_subscriptions = [s1] -> inactive_subscriptions = [s1]
        """

        # preparation
        observer = TObserver()
        self.subject.observe(init_observer_info(observer))

        # state change (change to the same state)
        ack = self.source.on_next_single(1)

        # verification
        self.assertIsInstance(ack, ContinueAck)
        self.assertEqual([1], observer.received)
        self.assertEqual(0, len(self.subject.shared_state.queue))

    def test_on_completed(self):
        """
               on_completed
        NormalState -> CompletedState
        """

        # preparation
        o1 = TObserver()
        self.subject.observe(init_observer_info(o1))

        # state change
        self.source.on_completed()

        # verification
        self.assertTrue(o1.is_completed)
        self.assertIsInstance(self.subject.state,
                              CacheServeFirstObservableSubject.CompletedState)

    def test_on_next_assynchronously(self):
        """
                                     on_next
        inactive_subscriptions = [s1] -> inactive_subscriptions = []
        """

        # preparation
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))

        # state change
        ack = self.source.on_next_single(1)

        # verification
        self.assertNotEqual(continue_ack, ack)
        self.assertEqual([1], o1.received)

    def test_on_next_assynchronously2(self):
        """
                                ack.on_next
        inactive_subscriptions = [] -> inactive_subscriptions = [s1]
        """

        # preparation
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        ack = self.source.on_next_single(1)

        # state change
        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        # verification
        self.assertEqual(len(self.subject.shared_state.inactive_subscriptions),
                         1)

    def test_on_next_multiple_elements_asynchronously(self):
        """
                 on_next
        queue = [] -> queue = [OnNext(2)]
        """

        # preparation
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.source.on_next_single(1)

        # state change
        self.source.on_next_single(2)

        # verification
        self.assertEqual([1], o1.received)
        queue = self.subject.shared_state.queue
        self.assertEqual(1, len(queue))
        self.assertEqual([2], queue[0].value)

    def test_on_next_assynchronously_enter_fast_loop(self):
        """
                        ack.on_next
        queue = [OnNext(2)] -> queue = []
        """

        #preparation
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.source.on_next_single(1)
        self.source.on_next_single(2)

        # enter fast loop
        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        # verification
        self.assertEqual([1, 2], o1.received)

    def test_on_next_assynchronously_iterate_in_fast_loop(self):
        """
                 on_next
        queue = [] -> queue = [OnNext(2)]
        """

        # preparation
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.source.on_next_single(1)
        self.source.on_next_single(2)
        self.source.on_next_single(3)

        # state change
        o1.immediate_continue = 1  # needs immediate continue to loop
        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        # validation
        self.assertEqual([1, 2, 3], o1.received)
        self.assertEqual(0, len(self.subject.shared_state.queue))

    def test_on_next_assynchronously_reenter_fast_loop(self):
        """
                        ack.on_next
        queue = [OnNext(3)] -> queue = []
        """

        # preparations
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.source.on_next_single(1)
        self.source.on_next_single(2)
        self.source.on_next_single(3)
        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        # state change
        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        # validation
        self.assertEqual([1, 2, 3], o1.received)
        self.assertEqual(0, len(self.subject.shared_state.queue))

    def test_on_next_two_subscribers_synchronously(self):
        """
                                     on_next
        inactive_subscriptions = [s1, s2] -> inactive_subscriptions = [s1, s2]
        """

        # preparation
        o1 = TObserver()
        o2 = TObserver()
        self.subject.observe(init_observer_info(o1))
        self.subject.observe(init_observer_info(o2))

        # state change
        ack = self.source.on_next_single(1)

        # verification
        self.assertIsInstance(ack, ContinueAck)
        self.assertEqual([1], o1.received)
        self.assertEqual([1], o2.received)
        self.assertEqual(0, len(self.subject.shared_state.queue))

    def test_on_next_multiple_elements_two_subscribers_asynchronously(self):
        """
                                       on_next
        inactive_subscriptions = [s1, s2] -> inactive_subscriptions = [s1, s2]
                               queue = [] -> queue = [OnNext(2)]
        """

        # preparation
        o1 = TObserver(immediate_continue=0)
        o2 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.subject.observe(init_observer_info(o2))
        self.source.on_next_single(1)

        # state change
        self.source.on_next_single(2)

        # validation
        self.assertEqual([1], o1.received)
        self.assertEqual([1], o2.received)
        self.assertEqual(1, len(self.subject.shared_state.queue))

    def test_on_next_enter_fast_loop_two_subscribers_asynchronously(self):
        o1 = TObserver(immediate_continue=0)
        o2 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.subject.observe(init_observer_info(o2))
        self.source.on_next_single(1)
        self.source.on_next_single(2)

        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], o1.received)
        self.assertEqual([1], o2.received)

    def test_on_next_enter_fast_loop_two_subscribers_asynchronously2(self):
        o1 = TObserver()
        o2 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.subject.observe(init_observer_info(o2))

        self.source.on_next_single(1)
        self.source.on_next_single(2)

        o2.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        o2.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.source.on_next_single(3)

        self.assertEqual([1, 2, 3], o1.received)
        self.assertEqual([1, 2, 3], o2.received)

    def test_on_error(self):
        """
               on_completed
        NormalState -> ErrorState
        """

        # preparation
        o1 = TObserver()
        self.subject.observe(init_observer_info(o1))

        # state change
        self.source.on_error(self.exc)

        # verification
        self.assertEqual(self.exc, o1.exception)
        self.assertIsInstance(self.subject.state,
                              CacheServeFirstObservableSubject.ExceptionState)

    def test_on_next_on_error_asynchronously(self):
        o1 = TObserver(immediate_continue=0)
        o2 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.subject.observe(init_observer_info(o2))

        ack = self.source.on_next_single(1)
        self.source.on_error(self.exc)

        # o2.ack.on_next(continue_ack)
        # self.scheduler.advance_by(1)

        # verification
        self.assertEqual(self.exc, o1.exception)
        self.assertEqual(self.exc, o2.exception)

    def test_on_error_two_subscribers_asynchronously(self):
        o1 = TObserver()
        o2 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.subject.observe(init_observer_info(o2))
        self.source.on_next_single(1)

        self.source.on_error(self.exc)

        self.assertEqual(self.exc, o1.exception)
        self.assertEqual(self.exc, o2.exception)

    def test_on_error_asynchronously(self):
        o1 = TObserver(immediate_continue=0)
        self.subject.observe(init_observer_info(o1))
        self.source.on_next_single(1)
        self.source.on_error(self.exc)

        o1.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual(self.exc, o1.exception)

    def test_on_disposed(self):
        sink = TObserver(immediate_continue=0)
        disposable = self.subject.observe(init_observer_info(sink))

        disposable.dispose()

        self.source.on_next_single(1)

        self.assertEqual([], sink.received)
class TestIteratorAsObservable(unittest.TestCase):
    def setUp(self) -> None:
        self.scheduler = TScheduler()

    def test_initialize(self):
        FromIteratorObservable(iterator=iter([]),
                               scheduler=self.scheduler,
                               subscribe_scheduler=self.scheduler)

    def test_empty_iterable(self):
        obs = FromIteratorObservable(iterator=iter([]),
                                     scheduler=self.scheduler,
                                     subscribe_scheduler=self.scheduler)
        sink = TObserver()

        obs.observe(init_observer_info(sink))
        self.scheduler.advance_by(1)

        self.assertEqual([], sink.received)
        self.assertTrue(sink.is_completed)

    def test_single_elem(self):
        obs = FromIteratorObservable(iterator=iter([[1]]),
                                     scheduler=self.scheduler,
                                     subscribe_scheduler=self.scheduler)
        sink = TObserver(immediate_continue=0)
        obs.observe(init_observer_info(sink))
        self.scheduler.advance_by(1)

        self.assertEqual([1], sink.received)
        self.assertTrue(sink.is_completed)

    def test_batch(self):
        obs = FromIteratorObservable(iterator=iter([[1, 2, 3]]),
                                     scheduler=self.scheduler,
                                     subscribe_scheduler=self.scheduler)
        sink = TObserver(immediate_continue=0)
        obs.observe(init_observer_info(sink))
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3], sink.received)
        self.assertTrue(sink.is_completed)

    def test_multiple_elem_sync_ack(self):
        obs = FromIteratorObservable(iterator=iter([[1], [2, 3], [4]]),
                                     scheduler=self.scheduler,
                                     subscribe_scheduler=self.scheduler)
        sink = TObserver()
        obs.observe(init_observer_info(sink))
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2, 3, 4], sink.received)
        self.assertTrue(sink.is_completed)

    def test_multiple_elem_async_ack(self):
        obs = FromIteratorObservable(iterator=iter([[1], [2]]),
                                     scheduler=self.scheduler,
                                     subscribe_scheduler=self.scheduler)
        sink = TObserver(immediate_continue=0)
        obs.observe(init_observer_info(sink))
        self.scheduler.advance_by(1)

        self.assertEqual([1], sink.received)
        self.assertFalse(sink.is_completed)

    def test_multiple_elem_async_ack_2nd_part(self):
        obs = FromIteratorObservable(iterator=iter([[1], [2]]),
                                     scheduler=self.scheduler,
                                     subscribe_scheduler=self.scheduler)
        sink = TObserver(immediate_continue=0)
        obs.observe(init_observer_info(sink))
        self.scheduler.advance_by(1)

        sink.ack.on_next(continue_ack)
        self.scheduler.advance_by(1)

        self.assertEqual([1, 2], sink.received)
        self.assertTrue(sink.is_completed)
Beispiel #19
0
class TestBackpressureBufferedObserver(unittest.TestCase):
    def setUp(self) -> None:
        self.source = TObservable()
        self.scheduler = TScheduler()

    def test_initialize(self):
        sink = TObserver()
        BufferedObserver(underlying=sink,
                         scheduler=self.scheduler,
                         subscribe_scheduler=self.scheduler,
                         buffer_size=0)

    def test_observe(self):
        sink = TObserver()
        observer = BufferedObserver(
            underlying=sink,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            buffer_size=1,
        )

        self.source.observe(init_observer_info(observer))

    def test_on_next_zero_buffer(self):
        sink = TObserver()
        observer = BufferedObserver(
            underlying=sink,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            buffer_size=0,
        )
        self.source.observe(init_observer_info(observer))

        ack = self.source.on_next_single(0)
        self.scheduler.advance_by(1)

        self.assertFalse(ack.is_sync)
        self.assertEqual([0], sink.received)

    def test_acknowledge_zero_buffer(self):
        sink = TObserver(immediate_continue=0)
        observer = BufferedObserver(
            underlying=sink,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            buffer_size=0,
        )
        self.source.observe(init_observer_info(observer))
        ack = self.source.on_next_single(0)
        self.scheduler.advance_by(1)

        sink.ack.on_next(continue_ack)

        self.assertIsInstance(ack.value, ContinueAck)

    def test_on_next(self):
        sink = TObserver()
        observer = BufferedObserver(
            underlying=sink,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            buffer_size=1,
        )
        self.source.observe(init_observer_info(observer))

        ack = self.source.on_next_single(0)
        self.scheduler.advance_by(1)

        self.assertIsInstance(ack, ContinueAck)
        self.assertEqual([0], sink.received)

    def test_fill_up_buffer(self):
        sink = TObserver()
        observer = BufferedObserver(
            underlying=sink,
            scheduler=self.scheduler,
            subscribe_scheduler=self.scheduler,
            buffer_size=1,
        )
        self.source.observe(init_observer_info(observer))
        self.source.on_next_single(0)

        ack = self.source.on_next_single(1)
        self.scheduler.advance_by(1)

        self.assertFalse(ack.is_sync)
        self.assertEqual([0, 1], sink.received)