1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#!/usr/bin/env python
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# found in the LICENSE file.
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import traceback
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import unittest
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from future import Future
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FutureTest(unittest.TestCase):
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def testNoValueOrDelegate(self):
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    self.assertRaises(ValueError, Future)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def testValue(self):
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    future = Future(value=42)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    self.assertEqual(42, future.Get())
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    self.assertEqual(42, future.Get())
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def testDelegateValue(self):
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    called = [False,]
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    def callback():
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      self.assertFalse(called[0])
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      called[0] = True
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return 42
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    future = Future(callback=callback)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    self.assertEqual(42, future.Get())
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    self.assertEqual(42, future.Get())
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def testErrorThrowingDelegate(self):
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    class FunkyException(Exception):
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pass
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    # Set up a chain of functions to test the stack trace.
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    def qux():
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      raise FunkyException()
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    def baz():
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return qux()
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    def bar():
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return baz()
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    def foo():
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return bar()
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    chain = [foo, bar, baz, qux]
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    called = [False,]
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    def callback():
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      self.assertFalse(called[0])
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      called[0] = True
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return foo()
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fail = self.fail
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assertTrue = self.assertTrue
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    def assert_raises_full_stack(future, err):
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      try:
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        future.Get()
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        fail('Did not raise %s' % err)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      except Exception as e:
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        assertTrue(isinstance(e, err))
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        stack = traceback.format_exc()
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        assertTrue(all(stack.find(fn.__name__) != -1 for fn in chain))
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    future = Future(callback=callback)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert_raises_full_stack(future, FunkyException)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert_raises_full_stack(future, FunkyException)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)if __name__ == '__main__':
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unittest.main()
71