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])
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_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_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)
class TestScanObserver(unittest.TestCase): def setUp(self) -> None: self.source = TObservable() def test_initialize(self): sink = TObserver() ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) def test_on_error(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) exc = Exception() self.source.on_error(exc) self.assertEqual(exc, sink.exception) def test_exception_during_on_next(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) exc = Exception() def gen_iter(): yield 1 raise exc self.source.on_next_iter(gen_iter()) self.assertEqual(exc, sink.exception) def test_on_completed(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) self.source.on_completed() self.assertTrue(sink.is_completed) def test_single_value(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_single(1) self.assertEqual([1], sink.received) def test_single_batch(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_list([1, 2, 3]) self.assertEqual([1, 3, 6], sink.received) def test_two_values(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_single(1) self.source.on_next_single(2) self.assertEqual([1, 3], sink.received) def test_two_batches(self): sink = TObserver() obs = ScanObserver( observer=sink, func=lambda acc, v: acc + v, initial=0, ) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_list([1, 2]) self.source.on_next_list([3, 4]) self.assertEqual([1, 3, 6, 10], sink.received)
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 TestTakeWhileObserver(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.source = TObservable() self.exception = Exception() def test_initialize(self): sink = TObserver() TakeWhileObserver( observer=sink, predicate=lambda _: True, ) def test_empty_sequence(self): sink = TObserver() observer = TakeWhileObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_completed() self.assertTrue(sink.is_completed) def test_on_error(self): sink = TObserver() observer = TakeWhileObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_error(self.exception) self.assertEqual(self.exception, sink.exception) def test_single_non_matching_element_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([0]) self.assertIsInstance(ack, StopAck) self.assertTrue(sink.is_completed) self.assertListEqual(sink.received, []) def test_single_matching_elements_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([1]) self.assertIsInstance(ack, ContinueAck) self.assertListEqual(sink.received, [1]) ack = self.source.on_next_list([1]) self.assertIsInstance(ack, ContinueAck) self.assertListEqual(sink.received, [1, 1]) ack = self.source.on_next_list([0]) self.assertIsInstance(ack, StopAck) self.assertListEqual(sink.received, [1, 1]) def test_list_and_complete_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([1, 1, 1]) self.assertIsInstance(ack, ContinueAck) self.assertEqual(1, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1]) self.source.on_completed() self.assertListEqual(sink.received, [1, 1, 1]) self.assertTrue(sink.is_completed) def test_list_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([1, 1, 1]) self.assertIsInstance(ack, ContinueAck) self.assertEqual(1, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1]) ack = self.source.on_next_list([1, 0, 1]) self.assertIsInstance(ack, StopAck) self.assertEqual(2, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1, 1]) self.assertTrue(sink.is_completed) def test_iterable_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_iter([1, 1, 1]) self.assertIsInstance(ack, ContinueAck) self.assertEqual(1, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1]) ack = self.source.on_next_iter([1, 0, 1]) self.assertIsInstance(ack, StopAck) self.assertEqual(2, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1, 1]) self.assertTrue(sink.is_completed) def test_failure_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) def gen_iterable(): for i in range(10): if i == 3: raise self.exception yield 1 ack = self.source.on_next_iter(gen_iterable()) self.assertIsInstance(ack, StopAck) self.assertEqual(0, sink.on_next_counter) self.assertListEqual([], sink.received) self.assertEqual(self.exception, sink.exception) def test_failure_after_non_matching_element_synchronously(self): sink = TObserver(immediate_continue=None) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) def gen_iterable(): for i in range(10): if i == 2: yield 0 elif i == 3: raise self.exception else: yield 1 ack = self.source.on_next_iter(gen_iterable()) self.assertIsInstance(ack, StopAck) self.assertEqual(1, sink.on_next_counter) self.assertListEqual([1, 1], sink.received) self.assertTrue(sink.is_completed) self.assertIsNone(sink.exception) def test_list_asynchronously(self): sink = TObserver(immediate_continue=0) observer = TakeWhileObserver( observer=sink, predicate=lambda v: v, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([1, 1, 1]) self.assertFalse(ack.is_sync) self.assertEqual(1, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1]) ack.on_next(continue_ack) ack = self.source.on_next_list([1, 0, 1]) self.assertIsInstance(ack, StopAck) self.assertEqual(2, sink.on_next_counter) self.assertListEqual(sink.received, [1, 1, 1, 1])
class TestPairwiseObserver(unittest.TestCase): def setUp(self) -> None: self.source = TObservable() self.sink = TObserver() def test_initialize(self): PairwiseObserver(self.sink) def test_first_single_elem(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_single(1) self.assertEqual(1, obs.last_elem) self.assertEqual([], self.sink.received) def test_first_multiple_elem(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_list([1, 2, 3]) self.assertEqual([(1, 2), (2, 3)], self.sink.received) def test_second_single_elem(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_single(1) self.source.on_next_single(2) self.assertEqual([(1, 2)], self.sink.received) def test_second_multiple_elem(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) self.source.on_next_list([1, 2]) self.source.on_next_list([3, 4]) self.assertEqual([(1, 2), (2, 3), (3, 4)], self.sink.received) def test_on_error(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) exc = Exception() self.source.on_error(exc) self.assertEqual(exc, self.sink.exception) def test_exception_during_on_next(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) exc = Exception() def gen_iter(): yield 1 raise exc self.source.on_next_iter(gen_iter()) self.assertEqual(exc, self.sink.exception) def test_on_completed(self): obs = PairwiseObserver(self.sink) self.source.observe(init_observer_info(observer=obs)) self.source.on_completed() self.assertTrue(self.sink.is_completed)