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