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 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 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 TestMergeSelectorObservable(unittest.TestCase): def setUp(self) -> None: self.left = TObservable() self.right = TObservable() self.scheduler = TScheduler() self.obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) self.exception = Exception() def measure_state(self, obs: MergeSelectorObservable): return obs.state.get_measured_state(obs.termination_state) def measure_termination_state(self, obs: MergeSelectorObservable): return obs.termination_state.get_measured_state() def test_initialize(self): obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) def test_state_waitonleftright_to_waitonleftright_with_leftonnext(self): """ left.on_next WaitOnLeftRight -----------------> WaitOnLeftRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack = self.left.on_next_list([select_completed]) self.assertIsInstance(ack, ContinueAck) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertEqual([select_completed], sink.received) def test_multiple_left_select_complete_should_not_wait_on_right(self): """ left.on_next WaitOnLeftRight -----------------> WaitOnLeftRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack = self.left.on_next_list( [select_completed, select_completed, select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertEqual( [select_completed, select_completed, select_completed], sink.received) self.assertIsInstance(ack, ContinueAck) def test_wait_on_left_right_to_wait_on_right(self): """ left.on_next WaitOnLeftRight -----------------> WaitOnRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack = self.left.on_next_list([select_next, select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnRight) self.assertEqual([], sink.received) self.assertFalse(ack.is_sync) def test_wait_on_right_to_wait_on_left_right(self): """ right.on_next WaitOnRight -----------------> WaitOnLeftRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack_left = self.left.on_next_list([select_next, select_completed]) ack_right = self.right.on_next_list([select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertEqual([select_completed], sink.received) self.assertIsInstance(ack_left.value, ContinueAck) self.assertIsInstance(ack_right, ContinueAck) def test_select_same_element_multiple_times(self): """ right.on_next WaitOnRight -----------------> WaitOnLeftRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack_left = self.left.on_next_list([select_next, select_completed]) ack_right = self.right.on_next_list( [select_next, select_next, select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertEqual([select_next, select_next, select_completed], sink.received) self.assertIsInstance(ack_left.value, ContinueAck) self.assertIsInstance(ack_right, ContinueAck) def test_state_waitonleft_to_waitonleftright(self): """ left.on_next WaitOnLeft -----------------> WaitOnLeftRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack_right = self.right.on_next_list([select_next, select_completed]) ack_left = self.left.on_next_list( [select_next, select_completed, select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertEqual([select_next, select_completed, select_completed], sink.received) self.assertIsInstance(ack_left, ContinueAck) self.assertIsInstance(ack_right.value, ContinueAck) def test_state_waitonleft_to_waitonleft(self): """ left.on_next WaitOnLeft ---------------------> WaitOnLeft InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack_right = self.right.on_next_list([select_next, select_completed]) ack_left = self.left.on_next_list([select_completed, select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeft) self.assertEqual([select_completed, select_completed], sink.received) self.assertIsInstance(ack_left, ContinueAck) self.assertFalse(ack_right.has_value) def test_drain_left_select_completed(self): """ right.on_next WaitOnRight -----------------> WaitOnLeftRight InitState InitState """ sink = TObserver() obs = MergeSelectorObservable( left=self.left, right=self.right, # scheduler=self.scheduler, ) obs.observe(init_observer_info(sink)) ack_left = self.left.on_next_list( [select_next, select_completed, select_completed]) ack_right = self.right.on_next_list([select_completed]) self.assertIsInstance(self.measure_termination_state(obs), TerminationStates.InitState) self.assertIsInstance(self.measure_state(obs), ControlledZipStates.WaitOnLeftRight) self.assertEqual([select_completed, select_completed], sink.received) self.assertIsInstance(ack_left.value, ContinueAck) self.assertIsInstance(ack_right, ContinueAck) def test_right_on_completed(self): """ right.on_completed left.on_next WaitOnLeft --------------------> WaitOnLeft ------------------> Stopped """ sink = TObserver(immediate_continue=0) self.obs.observe(init_observer_info(sink)) self.right.on_next_list([select_completed]) self.right.on_completed() self.assertIsInstance(self.measure_state(self.obs), ControlledZipStates.WaitOnLeft) self.left.on_next_list([select_next]) self.assertIsInstance(self.measure_state(self.obs), ControlledZipStates.Stopped) self.assertEqual([], sink.received) # the last SelectCompleted is optional def test_exception(self): """ right.on_error WaitOnRight -------------> Stopped """ sink = TObserver(immediate_continue=0) self.obs.observe(init_observer_info(sink)) ack1 = self.left.on_next_list([select_completed]) self.right.on_error(self.exception) self.assertIsInstance(self.measure_state(self.obs), ControlledZipStates.Stopped) self.assertEqual(self.exception, sink.exception)
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)
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)