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])
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 TestZip2Observable(TestCaseBase): """ Zip2Observable is a stateful object, therefore we test methods of Zip2Observable as a function of its states called "zip_state" of type Zip2Observable.ZipState and "termination_state" of type Zip2Observable.TerminationState. The termination state has four data types, which possibly have their own states. The join_flowables state has five data types, which possibly have their own states as well. Zip2Observable is symmetric to left and right source Observable. Therefore, the test specific to the left source Observable can be mirrored to get the test for the right source Observable. For non-concurrent testing, the state ZipElements can be ignored. The following method calls are prohibited by the rxbackpressure conventions: 1. left.on_next and right.on_next in state=ZipElements 2. left.on_next in state=WaitForRight 3. right.on_next in state=WaitForLeft The drawings in the comments for each test follow the following convention: action state1 ---------------> state2 state1: the state of ZipObservable before the action is applied action: on_next, on_completed, ack.on_next function calls state2: the state immediately after the action is applied """ def setUp(self): self.scheduler = TScheduler() self.left = TObservable() self.right = TObservable() self.exception = Exception('test') def measure_state(self, obs: ZipObservable): return obs.state.get_measured_state(obs.termination_state) def measure_termination_state(self, obs: ZipObservable): return obs.termination_state.get_measured_state() def test_init_state(self): sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnLeftRight) def test_left_complete(self): """ s1.on_completed WaitOnLeftRight -----------------> Stopped InitState LeftCompletedState """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) self.left.on_completed() self.assertIsInstance(self.measure_state(obs), ZipStates.Stopped) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertTrue(sink.is_completed) def test_right_complete(self): """ s2.on_completed WaitOnLeftRight -----------------> Stopped InitState RightCompletedState """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) self.right.on_completed() self.assertIsInstance(self.measure_state(obs), ZipStates.Stopped) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.RightCompletedState) self.assertTrue(sink.is_completed) def test_emit_left_with_synchronous_ack(self): """ s1.on_next WaitOnLeftRight ------------> WaitOnRight InitState InitState """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_single(1) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnRight) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertFalse(ack1.has_value) self.assertListEqual(sink.received, []) def test_zip_single_element_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnLeftRight """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_single(1) ack2 = self.right.on_next_single(1) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnLeftRight) self.assertIsInstance(ack1.value, ContinueAck) self.assertIsInstance(ack2, ContinueAck) self.assertListEqual(sink.received, [(1, 1)]) def test_multiple_elements_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnLeftRight """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1, 2, 3]) ack2 = self.right.on_next_list([1, 2, 3]) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnLeftRight) self.assertIsInstance(ack1.value, ContinueAck) self.assertIsInstance(ack2, ContinueAck) self.assertListEqual(sink.received, [(1, 1), (2, 2), (3, 3)]) def test_wait_on_right_to_wait_on_right_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnRight """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1, 2]) ack2 = self.right.on_next_list([1]) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnRight) self.assertFalse(ack1.has_value) self.assertIsInstance(ack2, ContinueAck) self.assertListEqual(sink.received, [(1, 1)]) def test_wait_on_right_to_wait_on_left_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnLeft """ sink = TObserver() obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1, 2]) ack2 = self.right.on_next_list([1, 2, 3]) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnLeft) self.assertIsInstance(ack1.value, ContinueAck) self.assertFalse(ack2.has_value) self.assertListEqual(sink.received, [(1, 1), (2, 2)]) def test_acknowledge_both(self): """ ack.on_next WaitOnRightLeft ------------> WaitOnRightLeft """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1]) ack2 = self.right.on_next_list([1]) sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnLeftRight) self.assertIsInstance(ack1.value, ContinueAck) self.assertIsInstance(ack2.value, ContinueAck) self.assertListEqual(sink.received, [(1, 1)]) def test_acknowledge_left(self): """ ack.on_next WaitOnLeft ------------> WaitOnLeft """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1]) ack2 = self.right.on_next_list([1, 2]) sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnLeft) self.assertIsInstance(ack1.value, ContinueAck) self.assertFalse(ack2.has_value) self.assertListEqual(sink.received, [(1, 1)]) def test_acknowledge_after_completed(self): """ ack.on_next Stopped ------------> Stopped """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1]) ack2 = self.right.on_next_list([1]) self.left.on_completed() sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), ZipStates.Stopped) self.assertListEqual(sink.received, [(1, 1)]) def test_exception(self): """ ack.on_next WaitOnRight ------------> Stopped """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1]) self.right.on_error(self.exception) self.assertEqual(sink.exception, self.exception) def test_left_complete_wait_on_right(self): """ s1.on_completed WaitOnLeftRight ------------> WaitOnRight InitState LeftCompletedState """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) self.left.on_next_list([1]) self.left.on_completed() self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnRight) def test_left_complete_to_stopped(self): """ s2.on_next WaitOnRight ------------> Stopped LeftComplete BothCompletedState """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) self.left.on_next_list([1]) self.left.on_completed() self.right.on_next_list([1]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertIsInstance(self.measure_state(obs), ZipStates.Stopped) self.assertListEqual(sink.received, [(1, 1)]) def test_left_complete_to_wait_on_right(self): """ s2.on_next WaitOnRight ------------> WaitOnRight LeftComplete LeftComplete """ sink = TObserver(immediate_continue=0) obs = ZipObservable(self.left, self.right) obs.observe(init_observer_info(sink)) self.left.on_next_list([1, 1]) self.left.on_completed() self.right.on_next_list([1]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertIsInstance(self.measure_state(obs), ZipStates.WaitOnRight) self.assertListEqual(sink.received, [(1, 1)])
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 TestControlledZipObservable(TestCaseBase): """ """ class Command: pass class Go(Command): pass class Stop(Command): pass def setUp(self): self.scheduler = TScheduler() self.left = TObservable() self.right = TObservable() self.exception = Exception() def measure_state(self, obs: ControlledZipObservable): return obs.state.get_measured_state(obs.termination_state) def measure_termination_state(self, obs: ControlledZipObservable): return obs.termination_state.get_measured_state() def test_init_state(self): sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) def test_left_complete(self): """ s1.on_completed WaitOnLeftRight -----------------> Stopped InitState LeftCompletedState """ sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) self.left.on_completed() self.assertIsInstance(self.measure_state(obs), ControlledZipStates.Stopped) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertTrue(sink.is_completed) def test_wait_on_left_right_to_wait_on_right_with_synchronous_ack(self): """ s1.on_next WaitOnLeftRight ------------> WaitOnRight InitState InitState """ sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_single(1) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnRight) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertFalse(ack1.has_value) self.assertListEqual(sink.received, []) def test_wait_on_right_to_wait_on_left_right_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnLeftRight """ sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_single(1) ack2 = self.right.on_next_single(1) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertIsInstance(ack1.value, ContinueAck) self.assertIsInstance(ack2, ContinueAck) self.assertListEqual(sink.received, [(1, 1)]) def test_wait_on_right_to_wait_on_right_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnRight """ sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_single(2) ack2 = self.right.on_next_single(1) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnRight) self.assertFalse(ack1.has_value) self.assertIsInstance(ack2, ContinueAck) self.assertListEqual(sink.received, []) def test_wait_on_right_to_wait_on_left_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnLeftRight """ sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_single(1) ack2 = self.right.on_next_single(2) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeft) self.assertIsInstance(ack1.value, ContinueAck) self.assertFalse(ack2.has_value) self.assertListEqual(sink.received, []) def test_wait_on_right_to_wait_on_left_right_multiple_elem_with_synchronous_ack(self): """ s2.on_next WaitOnRight ------------> WaitOnLeftRight """ sink = TObserver() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1, 1, 2]) ack2 = self.right.on_next_list([1, 2]) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertIsInstance(ack1.value, ContinueAck) self.assertIsInstance(ack2, ContinueAck) self.assertListEqual(sink.received, [(1, 1), (2, 2)]) def test_acknowledge_both(self): """ ack.on_next WaitOnRightLeft ------------> WaitOnRightLeft """ sink = TObserver(immediate_continue=0) obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1]) ack2 = self.right.on_next_list([1]) sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertIsInstance(ack1.value, ContinueAck) self.assertIsInstance(ack2.value, ContinueAck) self.assertListEqual(sink.received, [(1, 1)]) def test_left_complete_to_stopped(self): """ s2.on_next WaitOnRight ------------> Stopped LeftComplete BothCompletedState """ sink = TObserver(immediate_continue=0) obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) self.left.on_next_list([1]) self.left.on_completed() self.right.on_next_list([1]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.Stopped) self.assertListEqual(sink.received, [(1, 1)]) def test_exception(self): """ ack.on_next WaitOnRight ------------> Stopped """ sink = TObserver(immediate_continue=0) obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([1]) self.right.on_error(self.exception) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.Stopped) self.assertEqual(self.exception, sink.exception) def test_asynchronous_ack_from_selectors(self): """ ack.on_next WaitOnLeftRight ------------> WaitOnLeftRight """ sink = TObserver(immediate_continue=0) left_sel_sink = TObserver(immediate_continue=0) right_sel_sink = TObserver(immediate_continue=0) obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) obs.left_selector.observe(init_observer_info(left_sel_sink)) obs.right_selector.observe(init_observer_info(right_sel_sink)) ack1 = AckSubject() ack2 = AckSubject() self.left.on_next_single(1).subscribe(ack1) self.right.on_next_single(1).subscribe(ack2) sink.ack.on_next(continue_ack) self.assertFalse(ack1.has_value) left_sel_sink.ack.on_next(continue_ack) self.assertTrue(ack1.has_value) self.assertFalse(ack2.has_value) right_sel_sink.ack.on_next(continue_ack) self.assertTrue(ack1.has_value) self.assertTrue(ack2.has_value) def test_select_message_if_no_two_elements_match(self): """ ack.on_next WaitOnLeftRight ------------> WaitOnLeft """ sink = TObserver(immediate_continue=0) left_sel_sink = TObserver(immediate_continue=0) right_sel_sink = TObserver(immediate_continue=0) ack1 = AckSubject() ack2 = AckSubject() obs = ControlledZipObservable( left=self.left, right=self.right, scheduler=self.scheduler, request_left=lambda left, right: left <= right, request_right=lambda left, right: right <= left, match_func=lambda left, right: left == right, ) obs.observe(init_observer_info(sink)) obs.left_selector.observe(init_observer_info(left_sel_sink)) obs.right_selector.observe(init_observer_info(right_sel_sink)) self.left.on_next_single(1).subscribe(ack1) self.right.on_next_single(2).subscribe(ack2) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeft) self.assertIsInstance(left_sel_sink.received[0], SelectCompleted) self.left.on_next_single(2).subscribe(ack1) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) for instance_obj, class_obj in zip(left_sel_sink.received, [SelectCompleted, SelectNext, SelectCompleted]): self.assertIsInstance(instance_obj, class_obj)
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 TestMergeObservable(unittest.TestCase): def setUp(self): self.scheduler = TScheduler() self.s1 = TObservable() self.s2 = TObservable() self.exception = Exception('test') def measure_state(self, obs: MergeObservable): return obs.state.get_measured_state(obs.termination_state) def measure_termination_state(self, obs: MergeObservable): return obs.termination_state.get_measured_state() def test_init_state(self): sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) def test_emit_left_with_synchronous_ack(self): """ s1.on_next NoneReceived ------------> NoneReceived InitState InitState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) self.assertEqual(sink.received, [1]) def test_emit_right_with_synchronous_ack(self): """ s2.on_next NoneReceived ------------> NoneReceived InitState InitState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s2.on_next_single(2) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) self.assertEqual(sink.received, [2]) def test_left_complete_and_emit_right_with_synchronous_ack(self): """ s2.on_next NoneReceived ------------> NoneReceived LeftCompletedState LeftCompletedState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.s2.on_next_single(2) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) self.assertEqual(sink.received, [2]) def test_emit_left_with_asynchronous_ack(self): """ s1.on_next NoneReceived ------------> NoneReceivedWaitAck """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) left_ack = self.s1.on_next_single(1) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceivedWaitAck) self.assertEqual(sink.received, [1]) self.assertIsInstance(left_ack, ContinueAck) def test_emit_right_with_asynchronous_ack(self): """ s2.on_next NoneReceived ------------> NoneReceivedWaitAck """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) right_ack = self.s2.on_next_single(2) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceivedWaitAck) self.assertEqual(sink.received, [2]) self.assertIsInstance(right_ack, ContinueAck) def test_none_received_to_left_received_with_asynchronous_ack(self): """ s1.on_next NoneReceivedWaitAck ------------> LeftReceived """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) left_ack = self.s1.on_next_single(1) self.assertIsInstance(self.measure_state(obs), MergeStates.LeftReceived) self.assertEqual(sink.received, [1]) self.assertFalse(left_ack.has_value) def test_none_received_to_right_received_with_asynchronous_ack(self): """ s2.on_next NoneReceivedWaitAck ------------> RightReceived """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(2) left_ack = self.s1.on_next_single(2) self.assertIsInstance(self.measure_state(obs), MergeStates.LeftReceived) self.assertEqual(sink.received, [2]) self.assertFalse(left_ack.has_value) def test_left_received_to_both_received_with_asynchronous_ack(self): """ s2.on_next LeftReceived ------------> BothReceivedContinueLeft """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) self.s1.on_next_single(1) right_ack = self.s2.on_next_single(2) self.assertIsInstance(self.measure_state(obs), MergeStates.BothReceivedContinueLeft) self.assertEqual(sink.received, [1]) self.assertFalse(right_ack.has_value) def test_right_received_to_both_received_with_asynchronous_ack(self): """ s1.on_next RightReceived ------------> BothReceivedContinueRight """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s2.on_next_single(2) self.s2.on_next_single(2) left_ack = self.s1.on_next_single(1) self.assertIsInstance(self.measure_state(obs), MergeStates.BothReceivedContinueRight) self.assertEqual(sink.received, [2]) self.assertFalse(left_ack.has_value) def test_acknowledge_non_received(self): """ ack.on_next NoneReceivedWaitAck ------------> NoneReceived """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) self.assertEqual(sink.received, [1]) def test_acknowledge_left_received(self): """ ack.on_next LeftReceived ------------> NoneReceivedWaitAck """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) left_ack = self.s1.on_next_single(1) sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceivedWaitAck) self.assertEqual(sink.received, [1, 1]) self.assertIsInstance(left_ack.value, ContinueAck) def test_acknowledge_both_received(self): """ ack.on_next BothReceivedContinueLeft ------------> RightReceived """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) left_ack = self.s1.on_next_single(1) right_ack = self.s2.on_next_single(2) sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), MergeStates.RightReceived) self.assertEqual(sink.received, [1, 1]) self.assertIsInstance(left_ack.value, ContinueAck) self.assertFalse(right_ack.has_value) def test_wait_ack_and_continue_with_asynchronous_ack(self): """ ack.on_next Stopped -------------> Stopped """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) self.s1.on_completed() self.s2.on_completed() sink.ack.on_next(continue_ack) self.assertIsInstance(self.measure_state(obs), MergeStates.Stopped) self.assertEqual(sink.received, [1]) def test_left_complete(self): """ s1.on_completed NoneReceived -----------------> NoneReceived InitState LeftCompletedState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.assertFalse(sink.is_completed) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) def test_left_complete_to_both_complete(self): """ s1.on_completed NoneReceived -----------------> Stopped LeftCompletedState BothCompletedState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.s2.on_completed() self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.BothCompletedState) self.assertIsInstance(self.measure_state(obs), MergeStates.Stopped) self.assertTrue(sink.is_completed) def test_left_complete_to_error_asynchronous_ack(self): sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.s2.on_error(self.exception) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.ErrorState) self.assertIsInstance(self.measure_state(obs), MergeStates.Stopped) self.assertEqual(self.exception, sink.exception) def test_left_complete_on_next_right(self): """ s1.on_completed NoneReceived -----------------> NoneReceived InitState LeftCompletedState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.s2.on_next_single(1) self.assertEqual([1], sink.received) self.assertIsInstance(self.measure_state(obs), MergeStates.NoneReceived) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.LeftCompletedState) def test_left_complete_on_complete_right(self): """ s1.on_completed NoneReceived -----------------> NoneReceived InitState LeftCompletedState """ sink = TObserver() obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.s2.on_next_single(1) self.s2.on_completed() self.assertTrue(sink.is_completed) self.assertIsInstance(self.measure_state(obs), MergeStates.Stopped) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.BothCompletedState) def test_right_complete_on_async_ack(self): """ """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_completed() self.s2.on_next_single(1) ack = self.s2.on_next_single(2) self.s2.on_completed() sink.ack.on_next(continue_ack) self.assertEqual([1, 2], sink.received) self.assertTrue(sink.is_completed) def test_left_complete_on_async_ack2(self): """ """ sink = TObserver(immediate_continue=0) obs = MergeObservable(self.s1, self.s2) obs.observe(init_observer_info(sink)) self.s1.on_next_single(1) self.s1.on_next_single(2) ack = self.s2.on_next_single(11) self.s1.on_completed() sink.ack.on_next(continue_ack) sink.ack.on_next(continue_ack) self.assertEqual([1, 2, 11], sink.received) self.assertIsInstance(ack.value, ContinueAck)
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 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)