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