1"""
2Tests for accessing methods through classes and instances
3"""
4from PyObjCTools.TestSupport import *
5from PyObjCTest.clinmeth import *
6import objc
7
8class TestClassMethods (TestCase):
9    # Some very basic tests that check that getattr on instances doesn't
10    # return a class method and that getattr on classes prefers classmethods
11    # over instance methods (and v.v. for getattr on instances)
12
13    def testViaClass(self):
14        m = PyObjC_ClsInst1.clsmeth
15        self.assertIsInstance(m, objc.selector)
16        self.assertTrue(m.isClassMethod)
17
18        self.assertEqual(m(), 4)
19
20    def testViaInstance(self):
21        o = PyObjC_ClsInst1.alloc().init()
22        self.assertRaises(AttributeError, getattr, o, "clsmeth")
23
24    def testClassAndInstanceViaClass(self):
25        m = PyObjC_ClsInst1.both
26        self.assertIsInstance(m, objc.selector)
27        self.assertTrue( m.__metadata__()['classmethod'] )
28
29        self.assertEqual(m(), 3)
30
31    def testClassAndInstanceViaInstance(self):
32        o = PyObjC_ClsInst1.alloc().init()
33        m = o.both
34        self.assertTrue( isinstance(m, objc.selector) )
35        self.assertTrue( not m.isClassMethod )
36
37        self.assertEqual(m(), 2)
38
39
40class TestInstanceMethods (TestCase):
41    # Check that instance methods can be accessed through the instance, and
42    # also through the class when no class method of the same name is
43    # available.
44
45    def testViaClass(self):
46        m = PyObjC_ClsInst1.instance
47        self.assertTrue( isinstance(m, objc.selector) )
48        self.assertTrue( not m.isClassMethod )
49
50        self.assertRaises(TypeError, m)
51
52    def testViaInstance(self):
53        o = PyObjC_ClsInst1.alloc().init()
54        m = o.instance
55
56        self.assertIsInstance(m, objc.selector)
57        self.assertFalse(m.isClassMethod)
58
59        self.assertEqual(m(), 1)
60
61class TestSuper (TestCase):
62    # Tests that check if super() behaves as expected (which is the most likely
63    # reason for failure).
64
65    def testClassMethod(self):
66        cls = PyObjC_ClsInst2
67
68        self.assertEqual(cls.clsmeth(), 40)
69        self.assertEqual(objc.super(cls, cls).clsmeth(), 4)
70
71    def testInstanceMethod(self):
72        o = PyObjC_ClsInst2.alloc().init()
73
74        self.assertEqual(o.instance(), 10)
75        self.assertEqual(super(PyObjC_ClsInst2, o).instance(), 1)
76
77    def testBoth(self):
78        o = PyObjC_ClsInst2.alloc().init()
79
80        self.assertEqual(o.both(), 20)
81        self.assertEqual(objc.super(PyObjC_ClsInst2, o).both(), 2)
82
83        cls = PyObjC_ClsInst2
84
85        self.assertEqual(cls.both(), 30)
86        self.assertEqual(objc.super(cls, cls).both(), 3)
87
88
89if __name__ == "__main__":
90    main()
91