def test_simple_run(self): r = Runnable() # async run with valid state f = r.run(State()) self.assertIsInstance(f, Future) self.assertNotIsInstance(f, Present) self.assertRaises(NotImplementedError, f.result) # sync run with valid state f = r.run(State(), executor=immediate_executor) self.assertIsInstance(f, Present) self.assertRaises(NotImplementedError, f.result) # run with error state, check exc is propagated (default) f = r.run(Present(exception=ZeroDivisionError())) self.assertRaises(ZeroDivisionError, f.result) class MyRunnable(Runnable): def init(self, state): self.first = state.problem def next(self, state): return state.updated(problem=state.problem + 1) r = MyRunnable() s1 = State(problem=1) s2 = r.run(s1).result() self.assertEqual(r.first, s1.problem) self.assertEqual(s2.problem, s1.problem + 1)
def test_error_prop(self): class MyRunnable(Runnable): def next(self, state): return state def error(self, exc): return State(error=True) r = MyRunnable() s1 = Present(exception=KeyError()) s2 = r.run(s1).result() self.assertEqual(s2.error, True)
def test_exc(self): for exc in ValueError, KeyError, ZeroDivisionError: f = Present(exception=exc()) self.assertIsInstance(f, Future) self.assertTrue(f.done()) self.assertRaises(exc, f.result)
def test_res(self): for val in 1, 'x', True, False, State(problem=1), lambda: None: f = Present(result=val) self.assertIsInstance(f, Future) self.assertTrue(f.done()) self.assertEqual(f.result(), val)
def error(self, exc): """Pass on the exception from input to the error handler of the first runnable in branch. """ return self.next(Present(exception=exc))