testtools: Update to latest upstream snapshot.
[nivanova/samba-autobuild/.git] / lib / testtools / testtools / tests / test_helpers.py
index f1894a4613daff98a2462fe7a93b3caf11386163..55de34b7e729158e2307775c6dc34cc8eadef43c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Jonathan M. Lange. See LICENSE for details.
+# Copyright (c) 2010-2011 testtools developers. See LICENSE for details.
 
 from testtools import TestCase
 from testtools.helpers import (
@@ -6,9 +6,76 @@ from testtools.helpers import (
     try_imports,
     )
 from testtools.matchers import (
+    AllMatch,
+    AfterPreprocessing,
     Equals,
     Is,
+    Not,
     )
+from testtools.tests.helpers import (
+    FullStackRunTest,
+    hide_testtools_stack,
+    is_stack_hidden,
+    safe_hasattr,
+    )
+
+
+def check_error_callback(test, function, arg, expected_error_count,
+    expect_result):
+    """General test template for error_callback argument.
+
+    :param test: Test case instance.
+    :param function: Either try_import or try_imports.
+    :param arg: Name or names to import.
+    :param expected_error_count: Expected number of calls to the callback.
+    :param expect_result: Boolean for whether a module should
+        ultimately be returned or not.
+    """
+    cb_calls = []
+    def cb(e):
+        test.assertIsInstance(e, ImportError)
+        cb_calls.append(e)
+    try:
+        result = function(arg, error_callback=cb)
+    except ImportError:
+        test.assertFalse(expect_result)
+    else:
+        if expect_result:
+            test.assertThat(result, Not(Is(None)))
+        else:
+            test.assertThat(result, Is(None))
+    test.assertEquals(len(cb_calls), expected_error_count)
+
+
+class TestSafeHasattr(TestCase):
+
+    def test_attribute_not_there(self):
+        class Foo(object):
+            pass
+        self.assertEqual(False, safe_hasattr(Foo(), 'anything'))
+
+    def test_attribute_there(self):
+        class Foo(object):
+            pass
+        foo = Foo()
+        foo.attribute = None
+        self.assertEqual(True, safe_hasattr(foo, 'attribute'))
+
+    def test_property_there(self):
+        class Foo(object):
+            @property
+            def attribute(self):
+                return None
+        foo = Foo()
+        self.assertEqual(True, safe_hasattr(foo, 'attribute'))
+
+    def test_property_raises(self):
+        class Foo(object):
+            @property
+            def attribute(self):
+                1/0
+        foo = Foo()
+        self.assertRaises(ZeroDivisionError, safe_hasattr, foo, 'attribute')
 
 
 class TestTryImport(TestCase):
@@ -52,6 +119,19 @@ class TestTryImport(TestCase):
         import os
         self.assertThat(result, Is(os.path.join))
 
+    def test_error_callback(self):
+        # the error callback is called on failures.
+        check_error_callback(self, try_import, 'doesntexist', 1, False)
+
+    def test_error_callback_missing_module_member(self):
+        # the error callback is called on failures to find an object
+        # inside an existing module.
+        check_error_callback(self, try_import, 'os.nonexistent', 1, False)
+
+    def test_error_callback_not_on_success(self):
+        # the error callback is not called on success.
+        check_error_callback(self, try_import, 'os.path', 0, True)
+
 
 class TestTryImports(TestCase):
 
@@ -100,6 +180,60 @@ class TestTryImports(TestCase):
         import os
         self.assertThat(result, Is(os.path))
 
+    def test_error_callback(self):
+        # One error for every class that doesn't exist.
+        check_error_callback(self, try_imports,
+            ['os.doesntexist', 'os.notthiseither'],
+            2, False)
+        check_error_callback(self, try_imports,
+            ['os.doesntexist', 'os.notthiseither', 'os'],
+            2, True)
+        check_error_callback(self, try_imports,
+            ['os.path'],
+            0, True)
+
+
+import testtools.matchers
+import testtools.runtest
+import testtools.testcase
+
+
+def StackHidden(is_hidden):
+    return AllMatch(
+        AfterPreprocessing(
+            lambda module: safe_hasattr(module, '__unittest'),
+            Equals(is_hidden)))
+
+
+class TestStackHiding(TestCase):
+
+    modules = [
+        testtools.matchers,
+        testtools.runtest,
+        testtools.testcase,
+        ]
+
+    run_tests_with = FullStackRunTest
+
+    def setUp(self):
+        super(TestStackHiding, self).setUp()
+        self.addCleanup(hide_testtools_stack, is_stack_hidden())
+
+    def test_shown_during_testtools_testsuite(self):
+        self.assertThat(self.modules, StackHidden(False))
+
+    def test_is_stack_hidden_consistent_true(self):
+        hide_testtools_stack(True)
+        self.assertEqual(True, is_stack_hidden())
+
+    def test_is_stack_hidden_consistent_false(self):
+        hide_testtools_stack(False)
+        self.assertEqual(False, is_stack_hidden())
+
+    def test_show_stack(self):
+        hide_testtools_stack(False)
+        self.assertThat(self.modules, StackHidden(False))
+
 
 def test_suite():
     from unittest import TestLoader