blob: c760356fa05cf2ba4f2b2a590dc4a36f36df3015 [file] [log] [blame]
Guido van Rossumb5591132007-09-10 22:36:02 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Unit tests for abc.py."""
5
6import sys
7import unittest
8from test import test_support
9
10import abc
11__metaclass__ = type
12
13
14class TestABC(unittest.TestCase):
15
16 def test_abstractmethod_basics(self):
17 @abc.abstractmethod
18 def foo(self): pass
19 self.assertEqual(foo.__isabstractmethod__, True)
20 def bar(self): pass
21 self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
22
23 def test_abstractproperty_basics(self):
24 @abc.abstractproperty
25 def foo(self): pass
26 self.assertEqual(foo.__isabstractmethod__, True)
27 def bar(self): pass
28 self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
29
30 class C:
31 __metaclass__ = abc.ABCMeta
32 @abc.abstractproperty
33 def foo(self): return 3
34 class D(C):
35 @property
36 def foo(self): return super(D, self).foo
37 self.assertEqual(D().foo, 3)
38
39 def test_abstractmethod_integration(self):
40 for abstractthing in [abc.abstractmethod, abc.abstractproperty]:
41 class C:
42 __metaclass__ = abc.ABCMeta
43 @abstractthing
44 def foo(self): pass # abstract
45 def bar(self): pass # concrete
46 self.assertEqual(C.__abstractmethods__, set(["foo"]))
47 self.assertRaises(TypeError, C) # because foo is abstract
48 class D(C):
49 def bar(self): pass # concrete override of concrete
50 self.assertEqual(D.__abstractmethods__, set(["foo"]))
51 self.assertRaises(TypeError, D) # because foo is still abstract
52 class E(D):
53 def foo(self): pass
54 self.assertEqual(E.__abstractmethods__, set())
55 E() # now foo is concrete, too
56 class F(E):
57 @abstractthing
58 def bar(self): pass # abstract override of concrete
59 self.assertEqual(F.__abstractmethods__, set(["bar"]))
60 self.assertRaises(TypeError, F) # because bar is abstract now
61
62 def test_registration_basics(self):
63 class A:
64 __metaclass__ = abc.ABCMeta
65 class B:
66 pass
67 b = B()
68 self.assertEqual(issubclass(B, A), False)
69 self.assertEqual(isinstance(b, A), False)
70 A.register(B)
71 self.assertEqual(issubclass(B, A), True)
72 self.assertEqual(isinstance(b, A), True)
73 class C(B):
74 pass
75 c = C()
76 self.assertEqual(issubclass(C, A), True)
77 self.assertEqual(isinstance(c, A), True)
78
79 def test_registration_builtins(self):
80 class A:
81 __metaclass__ = abc.ABCMeta
82 A.register(int)
83 self.assertEqual(isinstance(42, A), True)
84 self.assertEqual(issubclass(int, A), True)
85 class B(A):
86 pass
87 B.register(basestring)
88 self.assertEqual(isinstance("", A), True)
89 self.assertEqual(issubclass(str, A), True)
90
91 def test_registration_edge_cases(self):
92 class A:
93 __metaclass__ = abc.ABCMeta
94 A.register(A) # should pass silently
95 class A1(A):
96 pass
97 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
98 class B:
99 pass
100 A1.register(B) # ok
101 A1.register(B) # should pass silently
102 class C(A):
103 pass
104 A.register(C) # should pass silently
105 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
106 C.register(B) # ok
107
108 def test_registration_transitiveness(self):
109 class A:
110 __metaclass__ = abc.ABCMeta
111 self.failUnless(issubclass(A, A))
112 class B:
113 __metaclass__ = abc.ABCMeta
114 self.failIf(issubclass(A, B))
115 self.failIf(issubclass(B, A))
116 class C:
117 __metaclass__ = abc.ABCMeta
118 A.register(B)
119 class B1(B):
120 pass
121 self.failUnless(issubclass(B1, A))
122 class C1(C):
123 pass
124 B1.register(C1)
125 self.failIf(issubclass(C, B))
126 self.failIf(issubclass(C, B1))
127 self.failUnless(issubclass(C1, A))
128 self.failUnless(issubclass(C1, B))
129 self.failUnless(issubclass(C1, B1))
130 C1.register(int)
131 class MyInt(int):
132 pass
133 self.failUnless(issubclass(MyInt, A))
134 self.failUnless(isinstance(42, A))
135
Guido van Rossum64c06e32007-11-22 00:55:51 +0000136 def test_all_new_methods_are_called(self):
137 class A:
138 __metaclass__ = abc.ABCMeta
139 class B:
140 counter = 0
141 def __new__(cls):
142 B.counter += 1
143 return super(B, cls).__new__(cls)
144 class C(A, B):
145 pass
146 self.assertEqual(B.counter, 0)
147 C()
148 self.assertEqual(B.counter, 1)
149
Guido van Rossumb5591132007-09-10 22:36:02 +0000150
151def test_main():
152 test_support.run_unittest(TestABC)
153
154
155if __name__ == "__main__":
156 unittest.main()