1from PyObjCTools.TestSupport import *
2import objc
3import types
4import sys
5
6from PyObjCTest.testhelper import PyObjC_TestClass3
7
8from Foundation import *
9
10
11class TestNSDictionarySubclassing(TestCase):
12    # These tests seem to be specific for MacOSX
13    def testExceptionInInit(self):
14        if objc.platform != 'MACOSX': return
15
16        class DictTestExceptionClass (NSDictionary):
17            pass
18
19        # Don't use self.assertRaises here, we once had a bug that
20        # causes this to fail, while the assertRaises version would
21        # (probably) have worked.
22        import warnings
23        warnings.filterwarnings('ignore',
24            category=objc.UninitializedDeallocWarning)
25
26        try:
27            try:
28                d = DictTestExceptionClass.alloc().initWithDictionary_({})
29                self.fail()
30            except ValueError:
31                pass
32        finally:
33            del warnings.filters[0]
34
35    def testAnotherExceptionInInit(self):
36        if objc.platform != 'MACOSX': return
37
38        class DictTestExceptionClass2 (NSDictionary):
39            def initWithObjects_forKeys_count_(self, o, k, c):
40                return super(DictTestExceptionClass2, self).initWithObjects_forKeys_count_(o, k, c)
41
42        import warnings
43        warnings.filterwarnings('ignore',
44            category=objc.UninitializedDeallocWarning)
45
46        try:
47            try:
48                d = DictTestExceptionClass2.alloc().initWithDictionary_({})
49                self.fail()
50            except ValueError:
51                pass
52        finally:
53            del warnings.filters[0]
54
55
56    def testExceptionInInitClsMeth(self):
57        if objc.platform != 'MACOSX': return
58
59        class DictTestExceptionClass3 (NSDictionary):
60            def initWithObjects_forKeys_count_(self, o, k, c):
61                return super(DictTestExceptionClass3, self).initWithObjects_forKeys_count_(o, k, c)
62
63        try:
64            d = DictTestExceptionClass3.dictionaryWithDictionary_({})
65            self.fail()
66        except ValueError:
67            pass
68
69
70class TestNSDictionaryInteraction(TestCase):
71    def testMethods(self):
72        for nm in dir(types.DictType):
73            if nm.startswith('__'):
74                continue
75
76            if isinstance(getattr(types.DictType, nm), (types.BuiltinFunctionType, types.FunctionType)):
77                # Skip class methods, that needs more work in the core
78                continue
79
80            self.assert_(hasattr(NSMutableDictionary, nm), "NSMutableDictionary has no method '%s'"%(nm,))
81
82    def testRepeatedAllocInit(self):
83        for i in range(1,1000):
84            d = NSDictionary.alloc().init()
85
86    def testBasicInteraction(self):
87        d = NSMutableDictionary.dictionary()
88        d[u'a'] = u"foo"
89        d[u'b'] = u"bar"
90
91        self.assertEqual(d[u'a'], u"foo", "Failed to retrieve the same thing that was put into the dict.")
92        try:
93            d[u'c']
94            self.fail("Should have raised...")
95        except KeyError:
96            pass
97
98    def testPythonIteraction(self):
99        d = NSMutableDictionary.dictionary()
100        d[u'a'] = u"foo"
101        d[u'b'] = u"bar"
102
103        k = list(d.keys())
104        k.sort()
105        self.assert_(k == [u'a', u'b'])
106
107        k = list(d.values())
108        k.sort()
109        self.assert_(k == [u'bar', u'foo'])
110
111        k = list(d.items())
112        k.sort()
113        self.assert_(k == [(u'a', u'foo'), (u'b', u'bar') ])
114
115
116    def testIn(self):
117        d = NSMutableDictionary.dictionary()
118        d[u'a'] = u"foo"
119        d[u'b'] = u"bar"
120        d[1] = u"baz"
121        d[0] = u"bob"
122        # d[-1] = None -- this fails because the bridge doesn't proxy py(None) to objc(NSNull)... not sure if it should
123
124        self.assert_( u'a' in d )
125        self.assert_( 1 in d )
126        # self.assert_( -1 in d )
127        # self.assert_( d[-1] is None )
128        self.assert_( u'q' not in d )
129
130        for k in d.allKeys():
131            self.assertEqual( d.objectForKey_( k ), d[k] )
132
133        for k in d:
134            self.assertEqual( d.objectForKey_( k ), d[k] )
135
136        del d[u'a']
137        self.assert_( u'a' not in d )
138
139    def test_varargConstruction(self):
140        u = NSDictionary.dictionaryWithObjects_forKeys_([1,2,3,4], [u'one', u'two', u'three', u'four'])
141        v = NSDictionary.alloc().initWithObjects_forKeys_([1,2,3,4], [u'one', u'two', u'three', u'four'])
142        w = NSDictionary.dictionaryWithObjects_forKeys_count_([1,2,3,4,5], [u'one', u'two', u'three', u'four', u'five'], 4)
143        x = NSDictionary.alloc().initWithObjects_forKeys_count_([1,2,3,4,5], [u'one', u'two', u'three', u'four', u'five'], 4)
144        y = NSDictionary.dictionaryWithObjectsAndKeys_(1, u'one', 2, u'two', 3, u'three', 4, u'four', None)
145        z = NSDictionary.alloc().initWithObjectsAndKeys_(1, u'one', 2, u'two', 3, u'three', 4, u'four', None)
146
147        self.assert_(len(u) == 4)
148        self.assert_(len(v) == 4)
149        self.assert_(len(w) == 4)
150        self.assert_(len(x) == 4)
151        self.assert_(len(y) == 4)
152        self.assert_(len(z) == 4)
153
154        self.assert_(u[u'one'] == 1)
155        self.assert_(v[u'two'] == 2)
156        self.assert_(w[u'three'] == 3)
157        self.assert_(x[u'one'] == 1)
158        self.assert_(y[u'two'] == 2)
159        self.assert_(z[u'four'] == 4)
160
161    def test_varargConstruction2(self):
162        u = NSMutableDictionary.dictionaryWithObjects_forKeys_([1,2,3,4], [u'one', u'two', u'three', u'four'])
163        v = NSMutableDictionary.alloc().initWithObjects_forKeys_([1,2,3,4], [u'one', u'two', u'three', u'four'])
164        w = NSMutableDictionary.dictionaryWithObjects_forKeys_count_([1,2,3,4,5], [u'one', u'two', u'three', u'four', u'five'], 4)
165        x = NSMutableDictionary.alloc().initWithObjects_forKeys_count_([1,2,3,4,5], [u'one', u'two', u'three', u'four', u'five'], 4)
166
167        #self.assertRaises(TypeError, NSMutableDictionary.dictionaryWithObjectsAndKeys_, 1, 'one', 2, 'two', None)
168        y = NSMutableDictionary.dictionaryWithObjectsAndKeys_(1, u'one', 2, u'two', 3, u'three', 4, u'four', None)
169        z = NSMutableDictionary.alloc().initWithObjectsAndKeys_(1, u'one', 2, u'two', 3, u'three', 4, u'four', None)
170
171        self.assert_(len(u) == 4)
172        self.assert_(len(v) == 4)
173        self.assert_(len(w) == 4)
174        self.assert_(len(x) == 4)
175        #self.assert_(len(y) == 4)
176        #self.assert_(len(z) == 4)
177
178        self.assert_(u[u'one'] == 1)
179        self.assert_(v[u'two'] == 2)
180        self.assert_(w[u'three'] == 3)
181        self.assert_(x[u'one'] == 1)
182        #self.assert_(y[u'two'] == 2)
183        #self.assert_(z[u'four'] == 4)
184
185
186class MyDictionaryBase (NSDictionary):
187    def count(self):
188        if hasattr(self, '_count'):
189            return self._count
190        return -1
191
192    def keyEnumerator(self):
193        return None
194
195    def objectForKey_(self, key):
196        return None
197
198class MyDictionary1 (MyDictionaryBase):
199    def initWithObjects_forKeys_count_(self, objects, keys, count):
200        self._count = count
201        self._objects = objects
202        self._keys = keys
203        return self
204
205class MyDictionary2 (MyDictionaryBase):
206    def dictionaryWithObjects_forKeys_count_(self, objects, keys, count):
207        if not self is MyDictionary2: raise AssertionError, self
208        return (objects, keys, count)
209
210class TestSubclassing (TestCase):
211    def testInitWithObjects(self):
212        o = PyObjC_TestClass3.makeDictFromClass_method_(MyDictionary1, 1)
213
214        self.assert_(isinstance(o, MyDictionary1))
215        self.assertEquals(o._count, 4)
216        self.assertEquals(len(o._keys), 4)
217        self.assertEquals(len(o._objects), 4)
218
219    def testDictWithObjects(self):
220        o = PyObjC_TestClass3.makeDictFromClass_method_(MyDictionary2, 0)
221
222        self.assert_(isinstance(o, tuple))
223        self.assertEquals(o[2], 4)
224        self.assertEquals(len(o[1]), 4)
225        self.assertEquals(len(o[0]), 4)
226
227class TestVariadic (TestCase):
228    def testDictionaryWithObjectsAndKeys(self):
229        o = NSDictionary.dictionaryWithObjectsAndKeys_(
230                42, 'a',
231                43, 'b')
232        self.assertEquals(o, {'a':42, 'b':43})
233        self.assert_(isinstance(o, NSDictionary))
234
235        o = NSMutableDictionary.dictionaryWithObjectsAndKeys_(
236                42, 'a',
237                43, 'b')
238        self.assertEquals(o, {'a':42, 'b':43})
239        self.assert_(isinstance(o, NSMutableDictionary))
240
241    def testInitWithObjectsAndKeys(self):
242        o = NSDictionary.alloc().initWithObjectsAndKeys_(
243                42, 'a',
244                43, 'b')
245        self.assertEquals(o, {'a':42, 'b':43})
246        self.assert_(isinstance(o, NSDictionary))
247
248        o = NSMutableDictionary.alloc().initWithObjectsAndKeys_(
249                42, 'a',
250                43, 'b')
251        self.assertEquals(o, {'a':42, 'b':43})
252        self.assert_(isinstance(o, NSMutableDictionary))
253
254
255class TestNSDictionary (TestCase):
256    def testMethods(self):
257        self.failUnlessResultIsBOOL(NSDictionary.isEqualToDictionary_)
258        self.failUnlessResultIsBOOL(NSDictionary.writeToFile_atomically_)
259        self.failUnlessArgIsBOOL(NSDictionary.writeToFile_atomically_, 1)
260        self.failUnlessResultIsBOOL(NSDictionary.writeToURL_atomically_)
261        self.failUnlessArgIsBOOL(NSDictionary.writeToURL_atomically_, 1)
262
263        self.failUnlessArgIsSEL(NSDictionary.keysSortedByValueUsingSelector_, 0, 'i@:@')
264
265        self.failUnlessArgIsIn(NSDictionary.dictionaryWithObjects_forKeys_count_, 0)
266        self.failUnlessArgSizeInArg(NSDictionary.dictionaryWithObjects_forKeys_count_, 0, 2)
267        self.failUnlessArgIsIn(NSDictionary.dictionaryWithObjects_forKeys_count_, 1)
268        self.failUnlessArgSizeInArg(NSDictionary.dictionaryWithObjects_forKeys_count_, 1, 2)
269
270        self.failUnlessArgIsIn(NSDictionary.initWithObjects_forKeys_count_, 0)
271        self.failUnlessArgSizeInArg(NSDictionary.initWithObjects_forKeys_count_, 0, 2)
272        self.failUnlessArgIsIn(NSDictionary.initWithObjects_forKeys_count_, 1)
273        self.failUnlessArgSizeInArg(NSDictionary.initWithObjects_forKeys_count_, 1, 2)
274
275        self.failUnlessArgIsBOOL(NSDictionary.initWithDictionary_copyItems_, 1)
276
277        self.failUnlessIsNullTerminated(NSDictionary.initWithObjectsAndKeys_)
278        self.failUnlessIsNullTerminated(NSDictionary.dictionaryWithObjectsAndKeys_)
279
280if __name__ == '__main__':
281    main( )
282