1from PyObjCTools.TestSupport import *
2import objc
3
4NSObject = objc.lookUpClass("NSObject")
5NSAutoreleasePool = objc.lookUpClass("NSAutoreleasePool")
6from PyObjCTest.copying import OC_CopyHelper, OC_CopyBase
7
8def funcattr(**kwds):
9    def annotate(func):
10        for k, v in kwds.iteritems():
11            setattr(func, k, v)
12        return func
13    return annotate
14
15class OC_TestCopy1 (NSObject):
16    def init(self):
17        self = super(OC_TestCopy1, self).init()
18        if self is not None:
19            self.x = 1
20            self.y = 2
21        return self
22
23    def modify(self):
24        self.x = 42
25        self.y = 24
26        self.z = 0
27
28    @funcattr(occlass="OC_TestCopy1")
29    def copyWithZone_(self, zone):
30        other = OC_TestCopy1.allocWithZone_(zone).init()
31        other.x = self.x
32        other.y = self.y
33        return other
34    # Argh, copyWithZone_ is a classmethod by default unless the
35    # superclass implements  -copyWithZone:
36    copyWithZone_ = objc.selector(copyWithZone_,
37            signature=NSObject.copyWithZone_.signature,
38            isClassMethod=False)
39
40class OC_TestCopy2 (OC_CopyBase):
41    def init(self):
42        self = super(OC_TestCopy2, self).initWithInt_(10)
43        if self is not None:
44            self.x = 1
45            self.y = 2
46        return self
47
48    def modify(self):
49        self.setIntVal_(40)
50        self.x = 42
51        self.y = 24
52        self.z = 0
53
54class OC_TestCopy3 (OC_CopyBase):
55    __slots__ = 'x y'.split()
56
57    def init(self):
58        self = super(OC_TestCopy3, self).initWithInt_(10)
59        if self is not None:
60            self.x = 1
61            self.y = 2
62        return self
63
64    def modify(self):
65        self.setIntVal_(40)
66        self.x = 42
67        self.y = 24
68
69class OC_TestCopy4 (OC_CopyBase):
70    def init(self):
71        self = super(OC_TestCopy4, self).initWithInt_(10)
72        if self is not None:
73            self.x = 1
74            self.y = 2
75        return self
76
77    def modify(self):
78        self.setIntVal_(40)
79        self.x = 42
80        self.y = 24
81        self.z = 0
82
83    @funcattr(occlass="OC_TestCopy4")
84    def copyWithZone_(self, zone):
85        other = super(OC_TestCopy4, self).copyWithZone_(zone)
86        other.x = self.x
87        other.y = self.y
88        other.z = "hello"
89        return other
90
91class TestNSCopyingHelper (NSObject):
92    def copyWithZone_(self, zone):
93        return 42
94
95class TestNSCopying (TestCase):
96    def testCopyingRegr20090327(self):
97        o = TestNSCopyingHelper.alloc().init()
98        v = o.copyWithZone_(None)
99        self.assertEqual(v, 42)
100
101    def testCopyingWithoutSuperFromObjC(self):
102        v = OC_TestCopy1.alloc().init()
103        self.assertFalse(v.copyWithZone_.isClassMethod)
104        self.assertEquals(v.copyWithZone_.callable.occlass, "OC_TestCopy1")
105        del v
106
107        p = NSAutoreleasePool.alloc().init()
108        o = OC_CopyHelper.doCopySetup_(OC_TestCopy1)
109        del p
110
111        self.assertEquals(o.x, 42)
112        self.assertEquals(o.y, 24)
113        self.assertRaises(AttributeError, getattr, o, 'z')
114
115    def testCopyingWithSuperFromObjC(self):
116        o = OC_CopyBase.alloc().init()
117        self.assertFalse(o.copyWithZone_.isClassMethod)
118        del o
119
120        o = OC_TestCopy2.alloc().init()
121        self.assertFalse(o.copyWithZone_.isClassMethod)
122        del o
123
124        o = OC_TestCopy3.alloc().init()
125        self.assertFalse(o.copyWithZone_.isClassMethod)
126        del o
127
128        o = OC_TestCopy4.alloc().init()
129        self.assertEquals(o.copyWithZone_.callable.occlass, "OC_TestCopy4")
130        del o
131
132        p = NSAutoreleasePool.alloc().init()
133        o = OC_CopyHelper.doCopySetup_(OC_TestCopy2)
134        del p
135
136        self.assertEquals(o.x, 42)
137        self.assertEquals(o.y, 24)
138        self.assertEquals(o.intVal(), 40)
139
140        p = NSAutoreleasePool.alloc().init()
141        o = OC_CopyHelper.doCopySetup_(OC_TestCopy3)
142        del p
143
144        self.assertEquals(o.x, 42)
145        self.assertEquals(o.y, 24)
146        self.assertEquals(o.intVal(), 40)
147
148        p = NSAutoreleasePool.alloc().init()
149        o = OC_CopyHelper.doCopySetup_(OC_TestCopy4)
150        del p
151
152        self.assertEquals(o.x, 42)
153        self.assertEquals(o.y, 24)
154        self.assertEquals(o.z, "hello")
155        self.assertEquals(o.intVal(), 40)
156
157    def testCopyingWithoutSuper(self):
158        v = OC_TestCopy1.alloc().init()
159        self.assertFalse(v.copyWithZone_.isClassMethod)
160        self.assertEquals(v.copyWithZone_.callable.occlass, "OC_TestCopy1")
161        del v
162
163        v = OC_TestCopy1.alloc().init()
164        v.modify()
165
166        p = NSAutoreleasePool.alloc().init()
167        o = v.copy()
168        v.x = 20
169        del v
170        del p
171
172        self.assertEquals(o.x, 42)
173        self.assertEquals(o.y, 24)
174        self.assertRaises(AttributeError, getattr, o, 'z')
175
176    def testCopyingWithSuper(self):
177        o = OC_CopyBase.alloc().init()
178        self.assertFalse(o.copyWithZone_.isClassMethod)
179        del o
180
181        o = OC_TestCopy2.alloc().init()
182        self.assertFalse(o.copyWithZone_.isClassMethod)
183        del o
184
185        o = OC_TestCopy3.alloc().init()
186        self.assertFalse(o.copyWithZone_.isClassMethod)
187        del o
188
189        o = OC_TestCopy4.alloc().init()
190        self.assertEquals(o.copyWithZone_.callable.occlass, "OC_TestCopy4")
191        del o
192
193        p = NSAutoreleasePool.alloc().init()
194        v = OC_TestCopy2.alloc().init()
195        v.modify()
196
197        o = v.copy()
198        v.x = 20
199        del v
200        del p
201
202        self.assertEquals(o.x, 42)
203        self.assertEquals(o.y, 24)
204        self.assertEquals(o.intVal(), 40)
205
206        p = NSAutoreleasePool.alloc().init()
207        v = OC_TestCopy3.alloc().init()
208        v.modify()
209
210        o = v.copy()
211        v.x = 20
212        del v
213        del p
214
215        self.assertEquals(o.x, 42)
216        self.assertEquals(o.y, 24)
217        self.assertEquals(o.intVal(), 40)
218
219        p = NSAutoreleasePool.alloc().init()
220        v = OC_TestCopy4.alloc().init()
221        v.modify()
222
223        o = v.copy()
224        v.x = 20
225        del v
226        del p
227
228        self.assertEquals(o.z, "hello")
229        self.assertEquals(o.y, 24)
230        self.assertEquals(o.x, 42)
231        self.assertEquals(o.intVal(), 40)
232
233
234NSMutableArray = objc.lookUpClass("NSMutableArray")
235import copy
236
237class TestPyCopyObjC (TestCase):
238    # Testcases that ensure that copy.copy works
239    # with Objective-C objects as well.
240
241    def testCopyArray(self):
242        a = NSMutableArray.arrayWithArray_(['a', 'b', 'c'])
243        self.assertIsInstance(a, NSMutableArray)
244
245        b = copy.copy(a)
246        self.assertIsInstance(b, NSMutableArray)
247        self.assertEquals(list(a), list(b))
248
249
250if __name__ == "__main__":
251    main()
252