class TestToListObserver(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.source = TObservable() self.exc = Exception() def test_initialize(self): sink = TObserver() ToListObserver(observer=sink, ) def test_on_complete(self): sink = TObserver() observer = ToListObserver(observer=sink, ) self.source.observe(init_observer_info(observer)) self.source.on_completed() self.assertEqual([[]], sink.received) self.assertTrue(sink.is_completed) def test_on_error(self): sink = TObserver() observer = ToListObserver(observer=sink, ) self.source.observe(init_observer_info(observer)) self.source.on_error(self.exc) self.assertEqual(self.exc, sink.exception) def test_single_element(self): sink = TObserver() observer = ToListObserver(observer=sink, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_single(0) self.assertEqual([], sink.received) self.assertIsInstance(ack, ContinueAck) self.assertFalse(sink.is_completed) self.source.on_completed() self.assertEqual([[0]], sink.received) self.assertTrue(sink.is_completed) def test_single_batch(self): sink = TObserver() observer = ToListObserver(observer=sink, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([0, 1, 2, 3]) self.assertEqual([], sink.received) self.assertIsInstance(ack, ContinueAck) self.assertFalse(sink.is_completed) self.source.on_completed() self.assertEqual([[0, 1, 2, 3]], sink.received) self.assertTrue(sink.is_completed)
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 TestFilterObserver(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.source = TObservable() self.exc = Exception() def test_initialize(self): sink = TObserver() FilterObserver( observer=sink, predicate=lambda _: True, ) def test_on_complete(self): sink = TObserver() observer = FilterObserver( 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 = FilterObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_error(self.exc) self.assertEqual(self.exc, sink.exception) def test_single_elem_not_fulfill_predicate(self): sink = TObserver() observer = FilterObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_next_single(0) self.assertEqual([], sink.received) def test_single_elem_fulfill_predicate(self): sink = TObserver() observer = FilterObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_next_single(1) self.assertEqual([1], sink.received) def test_single_batch(self): sink = TObserver() observer = FilterObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_next_list([0, 1, 0, 2]) self.assertEqual([1, 2], sink.received) def test_multiple_batches(self): sink = TObserver() observer = FilterObserver( observer=sink, predicate=lambda v: v > 0, ) self.source.observe(init_observer_info(observer)) self.source.on_next_list([1, 0]) self.source.on_next_list([0, 2]) self.assertEqual([1, 2], sink.received)
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)
class TestFirstObserver(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.source = TObservable() self.exc = Exception() def test_initialize(self): sink = TObserver() FirstObserver( observer=sink, stack=get_stack_lines(), ) def test_on_complete(self): sink = TObserver() observer = FirstObserver( observer=sink, stack=get_stack_lines(), ) self.source.observe(init_observer_info(observer)) self.source.on_completed() self.assertFalse(sink.is_completed) self.assertIsInstance(sink.exception, SequenceContainsNoElementsError) def test_on_error(self): sink = TObserver() observer = FirstObserver( observer=sink, stack=get_stack_lines(), ) self.source.observe(init_observer_info(observer)) self.source.on_error(self.exc) self.assertEqual(self.exc, sink.exception) def test_single_element(self): sink = TObserver() observer = FirstObserver( observer=sink, stack=get_stack_lines(), ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_single(0) self.assertEqual([0], sink.received) self.assertIsInstance(ack, StopAck) self.assertTrue(sink.is_completed) self.source.on_completed() self.assertEqual([0], sink.received) self.assertTrue(sink.is_completed) def test_single_batch(self): sink = TObserver() observer = FirstObserver( observer=sink, stack=get_stack_lines(), ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([0, 1, 2, 3]) self.assertEqual([0], sink.received) self.assertIsInstance(ack, StopAck) self.assertTrue(sink.is_completed)
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 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 TestDefaultIfEmptyObserver(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.source = TObservable() self.exc = Exception() def test_initialize(self): sink = TObserver() DefaultIfEmptyObserver( next_observer=sink, lazy_val=lambda: 0, ) def test_on_complete(self): sink = TObserver() observer = DefaultIfEmptyObserver( next_observer=sink, lazy_val=lambda: 0, ) self.source.observe(init_observer_info(observer)) self.source.on_completed() self.assertEqual([0], sink.received) self.assertTrue(sink.is_completed) def test_on_error(self): sink = TObserver() observer = DefaultIfEmptyObserver( next_observer=sink, lazy_val=lambda: 0, ) self.source.observe(init_observer_info(observer)) self.source.on_error(self.exc) self.assertEqual(self.exc, sink.exception) def test_single_element(self): sink = TObserver() observer = DefaultIfEmptyObserver( next_observer=sink, lazy_val=lambda: 0, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_single(1) self.assertEqual([1], sink.received) self.assertFalse(sink.is_completed) self.source.on_completed() self.assertTrue(sink.is_completed) def test_single_batch(self): sink = TObserver() observer = DefaultIfEmptyObserver( next_observer=sink, lazy_val=lambda: 0, ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([1, 2, 3]) self.assertEqual([1, 2, 3], sink.received)
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 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)
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)
class TestZipWithIndexObserver(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.source = TObservable() self.exc = Exception() def test_initialize(self): sink = TObserver() ZipCountObserver( observer=sink, selector=lambda v, idx: (v, idx), ) def test_on_complete(self): sink = TObserver() observer = ZipCountObserver( observer=sink, selector=lambda v, idx: (v, idx), ) self.source.observe(init_observer_info(observer)) self.source.on_completed() self.assertTrue(sink.is_completed) def test_on_error(self): sink = TObserver() observer = ZipCountObserver( observer=sink, selector=lambda v, idx: (v, idx), ) self.source.observe(init_observer_info(observer)) self.source.on_error(self.exc) self.assertEqual(self.exc, sink.exception) def test_single_element(self): sink = TObserver() observer = ZipCountObserver( observer=sink, selector=lambda v, idx: (v, idx), ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_single(0) self.assertEqual([(0, 0)], sink.received) self.assertIsInstance(ack, ContinueAck) self.assertFalse(sink.is_completed) self.source.on_completed() self.assertTrue(sink.is_completed) def test_multiple_element(self): sink = TObserver() observer = ZipCountObserver( observer=sink, selector=lambda v, idx: (v, idx), ) self.source.observe(init_observer_info(observer)) self.source.on_next_single(0) ack = self.source.on_next_single(1) self.assertEqual([(0, 0), (1, 1)], sink.received) self.assertIsInstance(ack, ContinueAck) self.assertFalse(sink.is_completed) self.source.on_completed() self.assertTrue(sink.is_completed) def test_single_batch(self): sink = TObserver() observer = ZipCountObserver( observer=sink, selector=lambda v, idx: (v, idx), ) self.source.observe(init_observer_info(observer)) ack = self.source.on_next_list([0, 1, 2, 3]) self.assertEqual([(0, 0), (1, 1), (2, 2), (3, 3)], sink.received) self.assertIsInstance(ack, ContinueAck) self.assertFalse(sink.is_completed) self.source.on_completed() self.assertTrue(sink.is_completed)