def test_then_multiple(self): base_f = ThenableFuture() new_f1 = base_f.then() new_f2 = base_f.then() new_f3 = base_f.then() self.assert_(base_f is not new_f1) self.assert_(base_f is not new_f2) self.assert_(base_f is not new_f3) self.assert_(not base_f.done()) self.assert_(not new_f1.done()) self.assert_(not new_f2.done()) self.assert_(not new_f3.done()) base_f.set_result('done') self.assert_(base_f.done()) self.assert_(new_f1.done()) self.assert_(new_f2.done()) self.assert_(new_f3.done()) self.assert_(not new_f1.exception()) self.assert_(not new_f2.exception()) self.assert_(not new_f3.exception()) self.assert_(new_f1.result() == 'done') self.assert_(new_f2.result() == 'done') self.assert_(new_f3.result() == 'done')
def transform(value): f = ThenableFuture() if value < 5: f.set_result(transform(value + 1)) else: f.set_result(value) return f
def test_detect_circular_chains(self): f1 = ThenableFuture() f2 = ThenableFuture() chain = [f1, f2, f1] def transform(a): try: f = chain.pop(0) f.set_result(transform(a)) return f except IndexError: return 42 base_f = ThenableFuture() new_f = base_f.then(transform) self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result(1) self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(new_f.exception()) with self.assertRaises(RuntimeError) as catcher: new_f.result() assert 'Circular future chain detected' in catcher.exception.args[0]
def test_then_multiple(self): base_f = ThenableFuture() new_f1 = base_f.then() new_f2 = base_f.then() new_f3 = base_f.then() self.assert_(base_f is not new_f1) self.assert_(base_f is not new_f2) self.assert_(base_f is not new_f3) self.assert_(not base_f.done()) self.assert_(not new_f1.done()) self.assert_(not new_f2.done()) self.assert_(not new_f3.done()) base_f.set_result('done') self.assert_(base_f.done()) self.assert_(new_f1.done()) self.assert_(new_f2.done()) self.assert_(new_f3.done()) self.assert_(not new_f1.exception()) self.assert_(not new_f2.exception()) self.assert_(not new_f3.exception()) self.assert_(new_f1.result() == 'done') self.assert_(new_f2.result() == 'done') self.assert_(new_f3.result() == 'done')
def test_detect_circular_chains(self): f1 = ThenableFuture() f2 = ThenableFuture() chain = [f1, f2, f1] def transform(a): try: f = chain.pop(0) f.set_result(transform(a)) return f except IndexError: return 42 base_f = ThenableFuture() new_f = base_f.then(transform) self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result(1) self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(new_f.exception()) with self.assertRaises(RuntimeError) as catcher: new_f.result() assert 'Circular future chain detected' in catcher.exception.args[0]
def transform(value): f = ThenableFuture() if value < 5: f.set_result(transform(value+1)) else: f.set_result(value) return f
def test_success_callback_and_success(self): base_f = ThenableFuture() new_f = base_f.then(lambda result: result + ' manipulated') self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result('done') self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(not new_f.exception()) self.assert_(new_f.result() == 'done manipulated')
def test_no_callbacks_and_success(self): base_f = ThenableFuture() new_f = base_f.then() self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result('done') self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(not new_f.exception()) self.assert_(new_f.result() == 'done')
def test_success_callback_and_success(self): base_f = ThenableFuture() new_f = base_f.then(lambda result: result + ' manipulated') self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result('done') self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(not new_f.exception()) self.assert_(new_f.result() == 'done manipulated')
def test_no_callbacks_and_success(self): base_f = ThenableFuture() new_f = base_f.then() self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result('done') self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(not new_f.exception()) self.assert_(new_f.result() == 'done')
def test_chained_success_callback_and_success(self): def transform(value): f = ThenableFuture() if value < 5: f.set_result(transform(value + 1)) else: f.set_result(value) return f base_f = ThenableFuture() new_f = base_f.then(transform) self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result(1) self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(not new_f.exception()) self.assert_(new_f.result() == 5)
def test_success_callback_and_failure_raised(self): class MyException(Exception): pass def raise_something_else(value): raise MyException(value + ' repackaged') base_f = ThenableFuture() new_f = base_f.then(raise_something_else) self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result('sad') self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(new_f.exception()) with self.assertRaises(MyException) as catcher: new_f.result() assert catcher.exception.args[0] == 'sad repackaged'
def test_chained_success_callback_and_success(self): def transform(value): f = ThenableFuture() if value < 5: f.set_result(transform(value+1)) else: f.set_result(value) return f base_f = ThenableFuture() new_f = base_f.then(transform) self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result(1) self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(not new_f.exception()) self.assert_(new_f.result() == 5)
def test_success_callback_and_failure_raised(self): class MyException(Exception): pass def raise_something_else(value): raise MyException(value + ' repackaged') base_f = ThenableFuture() new_f = base_f.then(raise_something_else) self.assert_(base_f is not new_f) self.assert_(not base_f.done()) self.assert_(not new_f.done()) base_f.set_result('sad') self.assert_(base_f.done()) self.assert_(new_f.done()) self.assert_(new_f.exception()) with self.assertRaises(MyException) as catcher: new_f.result() assert catcher.exception.args[0] == 'sad repackaged'