1# FIXME: This test suite seems to polute it's environment, other tests fail
2# when this test suite is active!
3from PyObjCTools.TestSupport import *
4import sys
5
6from PyObjCTools.TestSupport import onlyPython2
7
8import objc
9
10NSObject = objc.lookUpClass('NSObject')
11
12class MEClass(NSObject):
13    pass
14
15preEverythingInstance = MEClass.new()
16
17class Methods(NSObject):
18    def description(self):
19        return u"<methods>"
20
21    def newMethod(self):
22        return u"<new-method>"
23
24class MethodsSub(NSObject):
25    def description(self):
26        return u"<sub-methods>"
27
28    def newMethod(self):
29        return u"<sub-new-method>"
30
31    def newSubMethod(self):
32        return u"<new-method-sub>"
33
34class PurePython:
35    def description(self):
36        return u"<pure>"
37
38    def newMethod(self):
39        return u"<pure-new>"
40
41    def purePythonMethod(self):
42        return u"<pure-py>"
43
44class TestFromObjCSuperToObjCClass(TestCase):
45    def testBasicBehavior(self):
46        anInstance = Methods.new()
47        self.assertEquals(anInstance.description(), u"<methods>")
48        self.assertEquals(anInstance.newMethod(), u"<new-method>")
49
50    def testDescriptionOverride(self):
51        objc.classAddMethods(MEClass, [Methods.pyobjc_instanceMethods.description])
52
53        self.assertTrue(MEClass.instancesRespondToSelector_("description"))
54
55        newInstance = MEClass.new()
56
57        self.assertEquals(newInstance.description(), u"<methods>")
58        self.assertEquals(preEverythingInstance.description(), u"<methods>")
59
60    def testNewMethod(self):
61        objc.classAddMethods(MEClass, [Methods.pyobjc_instanceMethods.newMethod])
62
63        self.assertTrue(MEClass.instancesRespondToSelector_("newMethod"))
64
65        newInstance = MEClass.new()
66
67        self.assertEquals(newInstance.newMethod(), u"<new-method>")
68        self.assertEquals(preEverythingInstance.newMethod(), u"<new-method>")
69
70    def testSubDescriptionOverride(self):
71        objc.classAddMethods(MEClass, [MethodsSub.pyobjc_instanceMethods.description])
72
73        self.assertTrue(MEClass.instancesRespondToSelector_("description"))
74
75        newInstance = MEClass.new()
76
77        self.assertEquals(newInstance.description(), u"<sub-methods>")
78        self.assertEquals(preEverythingInstance.description(), u"<sub-methods>")
79
80    def testSubNewMethod(self):
81        objc.classAddMethods(MEClass, [MethodsSub.newMethod, MethodsSub.newSubMethod])
82
83        self.assertTrue(MEClass.instancesRespondToSelector_("newMethod"))
84        self.assertTrue(MEClass.instancesRespondToSelector_("newSubMethod"))
85
86        newInstance = MEClass.new()
87
88        self.assertEquals(newInstance.newMethod(), u"<sub-new-method>")
89        self.assertEquals(preEverythingInstance.newMethod(), u"<sub-new-method>")
90        self.assertEquals(newInstance.newSubMethod(), u"<new-method-sub>")
91        self.assertEquals(preEverythingInstance.newSubMethod(), u"<new-method-sub>")
92
93    def testNewClassMethod(self):
94
95        def aNewClassMethod(cls):
96            return "Foo cls"
97        aNewClassMethod = classmethod(aNewClassMethod)
98
99        self.assertTrue(not MEClass.pyobjc_classMethods.respondsToSelector_("aNewClassMethod"))
100        objc.classAddMethods(MEClass, [aNewClassMethod])
101        self.assertTrue(MEClass.pyobjc_classMethods.respondsToSelector_("aNewClassMethod"))
102
103        self.assertTrue(MEClass.aNewClassMethod.isClassMethod)
104        self.assertEquals(MEClass.aNewClassMethod(), 'Foo cls')
105
106    def testAddedMethodType(self):
107        def anotherNewClassMethod(cls):
108            "CLS DOC STRING"
109            return "BAR CLS"
110        anotherNewClassMethod = classmethod(anotherNewClassMethod)
111
112        def anotherNewMethod(self):
113            "INST DOC STRING"
114            return "BAR SELF"
115
116        self.assertTrue(not MEClass.pyobjc_classMethods.respondsToSelector_("anotherNewClassMethod"))
117        self.assertTrue(not MEClass.pyobjc_classMethods.instancesRespondToSelector_("anotherNewMethod"))
118
119        objc.classAddMethods(MEClass, [anotherNewClassMethod, anotherNewMethod])
120        self.assertTrue(MEClass.pyobjc_classMethods.respondsToSelector_("anotherNewClassMethod"))
121        self.assertTrue(MEClass.pyobjc_classMethods.instancesRespondToSelector_("anotherNewMethod"))
122
123        self.assertEquals(MEClass.anotherNewClassMethod.__doc__, "CLS DOC STRING")
124        self.assertEquals(MEClass.anotherNewMethod.__doc__, "INST DOC STRING")
125
126
127
128
129class TestFromPythonClassToObjCClass(TestCase):
130
131    @onlyPython2
132    def testPythonSourcedMethods(self):
133        # 20031227, Ronald: Assigning the methods works alright, but actually
134        # using them won't because the new methods are actually still methods
135        # of a different class and will therefore complain about the type
136        # of 'self'.
137        objc.classAddMethods(MEClass, [PurePython.description,
138                                                  PurePython.newMethod,
139                                                  PurePython.purePythonMethod])
140
141
142        self.assertTrue(MEClass.instancesRespondToSelector_("description"))
143        self.assertTrue(MEClass.instancesRespondToSelector_("newMethod"))
144        self.assertTrue(MEClass.instancesRespondToSelector_("purePythonMethod"))
145
146        newInstance = MEClass.new()
147
148        # This is bogus, see above:
149        #self.assertEquals(newInstance.description(), u"<pure>")
150        #self.assertEquals(newInstance.newMethod(), u"<pure-new>")
151        #self.assertEquals(newInstance.purePythonMethod(), u"<pure-py>")
152
153        #self.assertEquals(preEverythingInstance.description(), u"<pure>")
154        #self.assertEquals(preEverythingInstance.newMethod(), u"<pure-new>")
155        #self.assertEquals(preEverythingInstance.purePythonMethod(), u"<pure-py>")
156
157        self.assertRaises(TypeError, newInstance.description)
158        self.assertRaises(TypeError, newInstance.newMethod)
159        self.assertRaises(TypeError, newInstance.purePythonMethod)
160        self.assertRaises(TypeError, preEverythingInstance.description)
161        self.assertRaises(TypeError, preEverythingInstance.newMethod)
162        self.assertRaises(TypeError, preEverythingInstance.purePythonMethod)
163
164    def testPythonSourcedFunctions(self):
165        # Same as testPythonSourcedMethods, but using function objects instead
166        # of method objects.
167
168
169        if sys.version_info[0] == 2:
170            objc.classAddMethods(MEClass, [
171                PurePython.description.im_func,
172                PurePython.newMethod.im_func,
173                PurePython.purePythonMethod.im_func,
174            ])
175        else:
176            objc.classAddMethods(MEClass, [
177                PurePython.description,
178                PurePython.newMethod,
179                PurePython.purePythonMethod,
180            ])
181
182        self.assertTrue(MEClass.instancesRespondToSelector_("description"))
183        self.assertTrue(MEClass.instancesRespondToSelector_("newMethod"))
184        self.assertTrue(MEClass.instancesRespondToSelector_("purePythonMethod"))
185
186        newInstance = MEClass.new()
187
188        self.assertEquals(newInstance.description(), u"<pure>")
189        self.assertEquals(newInstance.newMethod(), u"<pure-new>")
190        self.assertEquals(newInstance.purePythonMethod(), u"<pure-py>")
191
192        self.assertEquals(preEverythingInstance.description(), u"<pure>")
193        self.assertEquals(preEverythingInstance.newMethod(), u"<pure-new>")
194        self.assertEquals(preEverythingInstance.purePythonMethod(), u"<pure-py>")
195
196
197
198class TestClassAsignments (TestCase):
199    def testAssignAMethod(self):
200        MEClass.doSomethingElse = lambda self: 2*2
201        MEClass.doDuplicate_ = lambda self, x: 2*x
202
203        self.assertTrue(MEClass.instancesRespondToSelector_("doSomethingElse"))
204        self.assertTrue(MEClass.instancesRespondToSelector_("doDuplicate:"))
205
206        o = MEClass.alloc().init()
207
208        self.assertEquals(4, o.doSomethingElse())
209        self.assertEquals(8, o.doDuplicate_(4))
210
211    def testAssignAClassMethod(self):
212        MEClass.classSomethingElse = classmethod(lambda self: 2*2)
213        MEClass.classDuplicate_ = classmethod(lambda self, x: 2*x)
214
215        self.assertTrue(MEClass.pyobjc_classMethods.respondsToSelector_(b"classSomethingElse"))
216        self.assertTrue(MEClass.pyobjc_classMethods.respondsToSelector_(b"classDuplicate:"))
217
218        self.assertEquals(4, MEClass.classSomethingElse())
219        self.assertEquals(8, MEClass.classDuplicate_(4))
220
221    def testAssignFuzzyMethod(self):
222        self.assertRaises((ValueError, TypeError), setattr, MEClass, 'fuzzyMethod', objc.selector(None, selector=b'fuzzy', signature=b'@@:'))
223
224    def testRemovingMethods(self):
225        theClass = NSObject
226
227        self.assertRaises(AttributeError, delattr, theClass, 'alloc')
228        self.assertRaises(AttributeError, delattr, theClass, 'init')
229
230class TestCategory (TestCase):
231    # Tests of objc.Category
232
233    def testPyClassCategory(self):
234        global Methods
235
236        o = Methods.alloc().init()
237        self.assertRaises(AttributeError, getattr, o, 'categoryMethod')
238
239        class Methods (objc.Category(Methods)):
240            def categoryMethod(self):
241                return True
242
243            def categoryMethod2(self):
244                return False
245
246            def anotherClassMethod(self):
247                return "hello"
248            anotherClassMethod = classmethod(anotherClassMethod)
249
250        self.assertTrue(o.categoryMethod())
251        self.assertTrue(not o.categoryMethod2())
252        self.assertEquals(Methods.anotherClassMethod(), "hello")
253
254    def testObjCClassCategory(self):
255        NSObject = objc.lookUpClass('NSObject')
256
257        o = NSObject.alloc().init()
258        self.assertRaises(AttributeError, getattr, o, 'myCategoryMethod')
259
260        class NSObject (objc.Category(NSObject)):
261            def myCategoryMethod(self):
262                return True
263
264            def myCategoryMethod2(self):
265                return False
266
267        self.assertTrue(o.myCategoryMethod())
268        self.assertTrue(not o.myCategoryMethod2())
269
270    def testCategoryMultipleInheritance(self):
271
272        NSObject = objc.lookUpClass('NSObject')
273
274
275        try:
276
277            class NSObject ( objc.Category(NSObject), object ):
278                pass
279
280            raise AssertionError, u"Can use objc.Category with MI"
281        except TypeError:
282            pass
283
284    def testCategoryName(self):
285        try:
286            class NSFoo (objc.Category(NSObject)):
287                    pass
288
289            raise AssertionError, u"Category name != class name"
290
291        except TypeError:
292            pass
293
294    def testCategoryOnPurePython(self):
295        try:
296            global list
297
298            class list (objc.Category(list)):
299                pass
300
301            raise AssertionError, u"Category on list???"
302
303        except TypeError:
304            pass
305
306    def testCategoryRedefiningPythonMethod(self):
307        class BaseClassRedef(NSObject):
308            def foo(self):
309                return 1
310
311        class BaseClassRedef(objc.Category(BaseClassRedef)):
312            def foo(self):
313                return 2
314
315        obj = BaseClassRedef.alloc().init()
316
317        self.assertEquals(obj.foo(), 2)
318
319        def foo(self):
320            return 3
321        BaseClassRedef.foo = foo
322
323        self.assertEquals(obj.foo(), 3)
324
325    def testCategeryWithDocString (self):
326        class NSObjectCat (NSObject):
327            pass
328
329        class NSObjectCat (objc.Category(NSObjectCat)):
330            """
331            This is a docstring
332            """
333
334            def withDocStringMethod(self):
335                return 42
336
337        o = NSObjectCat.alloc().init()
338        self.assertEqual(o.withDocStringMethod(), 42)
339
340    def testCategoryWithClassMethod(self):
341        class NSObjectCat2 (NSObject):
342            pass
343
344        class NSObjectCat2 (objc.Category(NSObjectCat2)):
345            @classmethod
346            def aClassMethod(cls):
347                return 1
348
349        self.assertEqual(NSObjectCat2.aClassMethod(), 1)
350
351    def testCategoryWithVariables(self):
352        class NSObjectCat3 (NSObject):
353            pass
354
355        class NSObjectCat3 (objc.Category(NSObjectCat3)):
356            classValue = "aap"
357
358            def getClassValue(self):
359                return self.classValue
360
361
362        self.assertHasAttr(NSObjectCat3, "classValue")
363        o = NSObjectCat3.alloc().init()
364        self.assertEqual(o.getClassValue(), "aap")
365
366
367
368
369if __name__ == '__main__':
370    main()
371