1"""
2Tests for the proxy of Python sets
3"""
4import sys
5from PyObjCTools.TestSupport import *
6from PyObjCTest.fnd import NSSet, NSMutableSet, NSPredicate, NSObject, NSNull
7from PyObjCTest.pythonset import OC_TestSet
8import objc
9
10import os
11
12onLeopard = int(os.uname()[2].split('.')[0]) >= 9
13
14OC_PythonSet = objc.lookUpClass("OC_PythonSet")
15
16class OC_SetPredicate (NSPredicate):
17    # A simple test predicate class
18    def initWithFunction_(self, pred):
19        self = super(OC_SetPredicate, self).init()
20        if self is None:
21            return None
22
23        self.pred = pred
24        return self
25
26    def evaluateWithObject_(self, object):
27        return self.pred(object)
28
29class OC_TestElem(NSObject):
30
31    def __new__(self, k):
32        return self.alloc().initWithK_(k)
33
34    def initWithK_(self, k):
35        super(OC_TestElem, self).init()
36        self.k = k
37        return self
38
39    def __eq__(self, other):
40        return self.k == other.k
41
42    def __hash__(self):
43        return hash(self.k)
44
45
46class BasicSetTests:
47    # Tests for sets that don't try to mutate the set.
48    # Shared between tests for set() and frozenset()
49    setClass = None
50
51    def testProxyClass(self):
52        # Ensure that the right class is used to proxy sets
53        self.assertIs(OC_TestSet.classOf_(self.setClass()), OC_PythonSet)
54
55    def testMutableCopy(self):
56
57        s = self.setClass(range(20))
58        o = OC_TestSet.set_mutableCopyWithZone_(s, None)
59        self.assertEquals(s, o)
60        self.assertIsNot(s, o)
61        self.assertIsInstance(o, set)
62
63        s = self.setClass()
64        o = OC_TestSet.set_mutableCopyWithZone_(s, None)
65        self.assertEquals(s, o)
66        self.assertIsNot(s, o)
67        self.assertIsInstance(o, set)
68
69
70    def testAllObject(self):
71        s = self.setClass()
72        self.assertEquals(OC_TestSet.allObjectsOfSet_(s), [])
73
74        s = self.setClass([1,2,3])
75        o = OC_TestSet.allObjectsOfSet_(s)
76        o.sort()
77        self.assertEquals(o, [1,2,3])
78
79    def testCount(self):
80        s = self.setClass()
81        self.assertEquals(OC_TestSet.countOfSet_(s), 0)
82
83        s = self.setClass([1,2,3])
84        self.assertEquals(OC_TestSet.countOfSet_(s), 3)
85
86    def testAnyObject(self):
87        s = self.setClass()
88        self.assertEquals(OC_TestSet.anyObjectOfSet_(s), None)
89
90        s = self.setClass([1,2,3,4])
91        self.assertIn(OC_TestSet.anyObjectOfSet_(s), s)
92
93    def testContainsObject_(self):
94        s = self.setClass([1,2,3])
95
96        self.assertFalse(OC_TestSet.set_containsObject_(s, 4))
97        self.assertTrue(OC_TestSet.set_containsObject_(s, 2))
98
99    if onLeopard:
100        def testFilteredSetUsingPredicate(self):
101            s = self.setClass(range(10))
102            p = OC_SetPredicate.alloc().initWithFunction_(lambda x: x % 2 == 0)
103
104            o = OC_TestSet.set_filteredSetUsingPredicate_(s, p)
105            self.assertEquals(o, self.setClass([0, 2, 4, 6, 8]))
106            self.assertEquals(len(s), 10)
107
108    def testMakeObjectsPerform(self):
109        o1 = OC_TestElem(1)
110        o2 = OC_TestElem(2)
111        o3 = OC_TestElem(3)
112        s = self.setClass([o1, o2, o3])
113
114        o = OC_TestSet.set_member_(s, OC_TestElem(4))
115        self.assertIsNone(o)
116
117        o = OC_TestSet.set_member_(s, OC_TestElem(2))
118        self.assertIs(o, o2)
119
120    def testObjectEnumerator(self):
121        s = self.setClass(range(10))
122
123        enum = OC_TestSet.objectEnumeratorOfSet_(s)
124        l = []
125        v = enum.nextObject()
126        while v is not None:
127            l.append(v)
128            v = enum.nextObject()
129        self.assertEquals(l, list(range(10)))
130
131        s = self.setClass([1, 2, None, 3])
132        enum = OC_TestSet.objectEnumeratorOfSet_(s)
133        l = []
134        v = enum.nextObject()
135        while v is not None:
136            l.append(v)
137            v = enum.nextObject()
138
139
140        self.assertEquals(dict.fromkeys(l), dict.fromkeys([1,2,NSNull.null(),3]))
141
142    def testIsSubSet(self):
143        s1 = self.setClass(range(10))
144        s2 = self.setClass(range(5))
145
146        self.assertTrue(OC_TestSet.set_isSubsetOfSet_(s2, s1))
147        self.assertTrue(OC_TestSet.set_isSubsetOfSet_(s2, s2))
148        self.assertFalse(OC_TestSet.set_isSubsetOfSet_(s1, s2))
149
150    def testIntersects(self):
151        s1 = self.setClass([1,2,3,4])
152        s2 = self.setClass([3,4,5,6])
153        s3 = self.setClass([5,6,7,8])
154
155        self.assertTrue(OC_TestSet.set_intersectsSet_(s1, s2))
156        self.assertTrue(OC_TestSet.set_intersectsSet_(s2, s3))
157        self.assertFalse(OC_TestSet.set_intersectsSet_(s1, s3))
158
159    def testDescription(self):
160        s = self.setClass([OC_TestElem(1), 2])
161        o = OC_TestSet.descriptionOfSet_(s)
162        self.assertIsInstance(o, unicode)
163
164
165class TestImmutableSet (TestCase, BasicSetTests):
166    setClass = frozenset
167
168    def testCopy(self):
169        s = self.setClass()
170        o = OC_TestSet.set_copyWithZone_(s, None)
171        self.assertEquals(s, o)
172
173        s = self.setClass(range(20))
174        o = OC_TestSet.set_copyWithZone_(s, None)
175        self.assertEquals(s, o)
176
177    def testNotMutable(self):
178        # Ensure that a frozenset cannot be mutated
179        o = self.setClass([1,2,3])
180        self.assertRaises((TypeError, AttributeError),
181                OC_TestSet.set_addObject_, o, 4)
182
183        self.assertRaises(TypeError,
184                OC_TestSet.set_removeObject_, o, 2)
185
186        self.assertRaises(TypeError,
187                OC_TestSet.set_addObjectsFromArray_, o, [4, 5, 6])
188
189        if onLeopard:
190            self.assertRaises(TypeError,
191                    OC_TestSet.set_filterUsingPredicate_, o,
192                    NSPredicate.predicateWithValue_(True))
193
194        self.assertRaises(TypeError,
195                OC_TestSet.set_intersectSet_, o, self.setClass([2,3,4]))
196
197        self.assertRaises(TypeError,
198                OC_TestSet.set_minusSet_, o, self.setClass([2,3,4]))
199
200        self.assertRaises(TypeError,
201                OC_TestSet.set_setSet_, o, self.setClass([2,3,4]))
202
203        self.assertRaises(TypeError,
204                OC_TestSet.set_minusSet_, o, self.setClass([2,3,4]))
205
206        self.assertRaises(TypeError,
207                OC_TestSet.removeAllObjecsFromSet_, o)
208
209
210class TestMutableSet (TestCase, BasicSetTests):
211    setClass = set
212
213    def testCopy(self):
214        s = self.setClass()
215        o = OC_TestSet.set_copyWithZone_(s, None)
216        self.assertEquals(s, o)
217        self.assertIsNot(s, o)
218
219        s = self.setClass(range(20))
220        o = OC_TestSet.set_copyWithZone_(s, None)
221        self.assertEquals(s, o)
222        self.assertIsNot(s, o)
223
224    def testUnionSet(self):
225        s1 = self.setClass([1,2,3])
226        s2 = self.setClass([3,4,5])
227
228        OC_TestSet.set_unionSet_(s1, s2)
229        self.assertEquals(s1, self.setClass([1,2,3,4,5]))
230
231    def testSetSet(self):
232        s1 = self.setClass([1,2,3])
233        s2 = self.setClass([3,4,5])
234
235        OC_TestSet.set_setSet_(s1, s2)
236        self.assertEquals(s1, self.setClass([3,4,5]))
237
238    def testMinusSet(self):
239        s1 = self.setClass([1,2,3])
240        s2 = self.setClass([3,4,5])
241
242        OC_TestSet.set_minusSet_(s1, s2)
243        self.assertEquals(s1, self.setClass([1, 2]))
244
245    def testIntersectSet(self):
246        s1 = self.setClass([1,2,3])
247        s2 = self.setClass([3,4,5])
248
249        OC_TestSet.set_intersectSet_(s1, s2)
250        self.assertEquals(s1, self.setClass([3]))
251
252    if onLeopard:
253        def testFilterSet(self):
254            s = self.setClass(range(10))
255            p = OC_SetPredicate.alloc().initWithFunction_(lambda x: x % 2 == 0)
256
257            OC_TestSet.set_filterUsingPredicate_(s, p)
258            self.assertEquals(s, self.setClass([0, 2, 4, 6, 8]))
259
260    def testAddObject(self):
261        s = self.setClass([1,2,3])
262
263        OC_TestSet.set_addObject_(s, 1)
264        self.assertEquals(s, self.setClass([1,2,3]))
265
266        OC_TestSet.set_addObject_(s, 9)
267        self.assertEquals(s, self.setClass([1,2,3,9]))
268
269    def testAddObjectsFromArray(self):
270        s = self.setClass([1,2,3])
271
272        OC_TestSet.set_addObjectsFromArray_(s, [1,2])
273        self.assertEquals(s, self.setClass([1,2,3]))
274
275        OC_TestSet.set_addObjectsFromArray_(s, [9,5,4])
276        self.assertEquals(s, self.setClass([1,2,3,9,5,4]))
277
278    def testRemoveObject(self):
279        s = self.setClass([1,2,3])
280
281        OC_TestSet.set_removeObject_(s, 1)
282        self.assertEquals(s, self.setClass([2,3]))
283
284        OC_TestSet.set_removeObject_(s, 9)
285        self.assertEquals(s, self.setClass([2,3]))
286
287    def testRemoveAllObjects(self):
288        s = self.setClass([1,2,3])
289
290        OC_TestSet.removeAllObjecsFromSet_(s)
291        self.assertEquals(s, self.setClass())
292
293
294
295if __name__ == "__main__":
296    main()
297