1from PyObjCTools.TestSupport import *
2import types
3import warnings
4import sys
5
6from Foundation import *
7
8class TestNSString(TestCase):
9    def testClassTree(self):
10        self.assert_(issubclass(objc.pyobjc_unicode, unicode))
11
12    def testCompare(self):
13        self.assert_(
14            NSString.localizedCaseInsensitiveCompare_(u'foo',u'bar') == 1,
15            u"NSString doesn't compare correctly")
16        self.assert_(
17            NSString.localizedCaseInsensitiveCompare_(u'foo',u'Foo') == 0,
18            u"NSString doesn't compare correctly")
19
20    def testFormatting(self):
21        # The test on instances is slightly more verbose to avoid warnings
22        obj = NSString.alloc().initWithFormat_(u"foo %d", 42)
23        self.assertEqual(obj, u"foo 42")
24
25        obj = NSString.alloc().initWithFormat_locale_(u"foo %d", {}, 42)
26        self.assertEqual(obj, u"foo 42")
27
28
29    def testGetCString(self):
30        # Custom wrappers
31        v = NSString.stringWithString_(u"hello world")
32
33        self.assertEqual(v, u"hello world")
34
35        x = v.getCString_maxLength_(None, 16)
36        self.assertEqual(x, b"hello world")
37
38        self.assertRaises(objc.error, v.getCString_maxLength_, None, 4)
39
40        x, l = v.getCString_maxLength_range_remainingRange_(None, 4, (1, 4), None)
41        self.assertEqual(x, b"ello")
42        self.assertEqual(l.location, 5)
43        self.assertEqual(l.length, 0)
44
45
46class TestNSStringBridging(TestCase):
47    def setUp(self):
48        self.nsUniString = NSString.stringWithString_(u"unifoo")
49        self.pyUniString = u"unifoo"
50
51    def testBasicComparison(self):
52        self.assertEqual(u"unifoo", NSString.stringWithString_(u"unifoo"))
53
54        u = u'\xc3\xbc\xc3\xb1\xc3\xae\xc3\xa7\xc3\xb8d\xc3\xa8'
55        self.assertEqual(u, NSString.stringWithString_(u));
56
57    def testTypesAndClasses(self):
58        self.assert_(isinstance(self.nsUniString, unicode))
59        self.assert_(isinstance(self.pyUniString, unicode))
60
61    @onlyPython2
62    def testStrConversion(self):
63        curEnabledFlag = objc.getStrBridgeEnabled()
64        objc.setStrBridgeEnabled(True)
65        try:
66            v = NSString.stringWithString_("hello2")
67            self.assert_(isinstance(v, objc.pyobjc_unicode))
68            self.assertEqual(v, u"hello2")
69
70
71            self.assertRaises(UnicodeError, unicode, "\xff")
72            # XXX: string bridge now uses the default NSString encoding
73            # self.assertRaises(UnicodeError, NSString.stringWithString_, '\xff')
74
75            objc.setStrBridgeEnabled(False)
76
77            warnings.filterwarnings('error', category=objc.PyObjCStrBridgeWarning)
78            try:
79                #v = NSString.stringWithString_("hello")
80
81                # we need to make sure that the str is unique
82                # because an already bridged one might have crossed
83                # and would be cached
84                newString = type('test_str', (str,), {})('hello2')
85                self.assertRaises(objc.PyObjCStrBridgeWarning,
86                        NSString.stringWithString_, newString)
87
88            finally:
89                del warnings.filters[0]
90
91
92        finally:
93            objc.setStrBridgeEnabled(curEnabledFlag)
94
95    def testNSStringMethodAccess(self):
96        self.assert_(isinstance(self.nsUniString, objc.pyobjc_unicode))
97        v = self.nsUniString.stringByAppendingString_
98        self.assert_(isinstance(v, objc.selector))
99
100class TestMutable(TestCase):
101    def testSync(self):
102        """
103        Test that python and ObjC string representation are not
104        automaticly synchronized.
105        """
106        pyStr = NSMutableString.stringWithString_(u"hello")
107        ocStr= pyStr.nsstring()
108        self.assertEqual(pyStr, u"hello")
109        self.assert_(isinstance(ocStr, NSMutableString))
110        ocStr.appendString_(u" world")
111        self.assertEqual(pyStr, u"hello")
112
113class TestPickle(TestCase):
114    """
115    Testcases for pickling of Objective-C strings. Those are pickled as
116    unicode strings.
117    """
118
119    def setUp(self):
120        self.strVal = NSTaskDidTerminateNotification
121
122    def testPickle(self):
123        """
124        Check that ObjC-strings pickle as unicode strings
125        """
126        import pickle
127
128        s = pickle.dumps(self.strVal, 0)
129        v = pickle.loads(s)
130        self.assertEqual(type(v), types.UnicodeType)
131
132        s = pickle.dumps(self.strVal, 1)
133        v = pickle.loads(s)
134        self.assertEqual(type(v), types.UnicodeType)
135
136        s = pickle.dumps(self.strVal, 2)
137        v = pickle.loads(s)
138        self.assertEqual(type(v), types.UnicodeType)
139
140    def testCPickle(self):
141        """
142        Check that ObjC-strings pickle as unicode strings
143        """
144        import cPickle as pickle
145
146        s = pickle.dumps(self.strVal, 0)
147        v = pickle.loads(s)
148        self.assertEqual(type(v), types.UnicodeType)
149
150        s = pickle.dumps(self.strVal, 1)
151        v = pickle.loads(s)
152        self.assertEqual(type(v), types.UnicodeType)
153
154        s = pickle.dumps(self.strVal, 2)
155        v = pickle.loads(s)
156        self.assertEqual(type(v), types.UnicodeType)
157
158    def testFormat(self):
159        v = self.strVal
160
161        d = v.stringByAppendingFormat_(u"hello")
162        self.assertEqual(d, v + u'hello')
163
164        d = v.stringByAppendingFormat_(u"hello %s %d", b"world", 101)
165        self.assertEqual(d, v + u'hello world 101')
166
167        v = NSString.alloc().initWithFormat_("%s %d %s", b"a", 44, b"cc")
168        self.assertEqual(v, "a 44 cc")
169
170        v = NSString.alloc().initWithFormat_locale_("%s %d %s", None, b"a", 44, b"cc")
171        self.assertEqual(v, "a 44 cc")
172
173        v = NSString.stringWithFormat_("aap %s mies", b"noot")
174        self.assertEqual(v, "aap noot mies")
175
176        v = NSString.localizedStringWithFormat_("aap %s mies", b"noot")
177        self.assertEqual(v, "aap noot mies")
178
179
180        v = NSMutableString.stringWithString_("hello")
181        v.appendFormat_(" bar %s", b"baz")
182        self.assertEqual(v.nsstring(), "hello bar baz")
183
184
185    @min_os_level('10.5')
186    def testConstants10_5(self):
187        self.assertEqual(NSMaximumStringLength, sys.maxint-1)
188        self.assertEqual(NSDiacriticInsensitiveSearch, 128)
189        self.assertEqual(NSWidthInsensitiveSearch, 256)
190        self.assertEqual(NSForcedOrderingSearch, 512)
191
192        self.assertEqual(NSProprietaryStringEncoding, 65536)
193
194    def testConstants(self):
195        self.assertIsInstance(NSParseErrorException, unicode)
196        self.assertIsInstance(NSCharacterConversionException, unicode)
197
198        self.assertEqual(NSCaseInsensitiveSearch, 1)
199        self.assertEqual(NSLiteralSearch, 2)
200        self.assertEqual(NSBackwardsSearch, 4)
201        self.assertEqual(NSAnchoredSearch, 8)
202        self.assertEqual(NSNumericSearch, 64)
203        self.assertEqual(NSASCIIStringEncoding, 1)
204        self.assertEqual(NSNEXTSTEPStringEncoding, 2)
205        self.assertEqual(NSJapaneseEUCStringEncoding, 3)
206        self.assertEqual(NSUTF8StringEncoding, 4)
207        self.assertEqual(NSISOLatin1StringEncoding, 5)
208        self.assertEqual(NSSymbolStringEncoding, 6)
209        self.assertEqual(NSNonLossyASCIIStringEncoding, 7)
210        self.assertEqual(NSShiftJISStringEncoding, 8)
211        self.assertEqual(NSISOLatin2StringEncoding, 9)
212        self.assertEqual(NSUnicodeStringEncoding, 10)
213        self.assertEqual(NSWindowsCP1251StringEncoding, 11)
214        self.assertEqual(NSWindowsCP1252StringEncoding, 12)
215        self.assertEqual(NSWindowsCP1253StringEncoding, 13)
216        self.assertEqual(NSWindowsCP1254StringEncoding, 14)
217        self.assertEqual(NSWindowsCP1250StringEncoding, 15)
218        self.assertEqual(NSISO2022JPStringEncoding, 21)
219        self.assertEqual(NSMacOSRomanStringEncoding, 30)
220        self.assertEqual(NSUTF16StringEncoding, NSUnicodeStringEncoding)
221        self.assertEqual(NSUTF16BigEndianStringEncoding, cast_int(0x90000100))
222        self.assertEqual(NSUTF16LittleEndianStringEncoding, cast_int(0x94000100))
223        self.assertEqual(NSUTF32StringEncoding, cast_int(0x8c000100))
224        self.assertEqual(NSUTF32BigEndianStringEncoding, cast_int(0x98000100))
225        self.assertEqual(NSUTF32LittleEndianStringEncoding, cast_int(0x9c000100))
226        self.assertEqual(NSStringEncodingConversionAllowLossy, 1)
227        self.assertEqual(NSStringEncodingConversionExternalRepresentation, 2)
228
229    def testMethods(self):
230        self.assertArgHasType(NSString.getCharacters_range_, 0, b'o^' + objc._C_UNICHAR)
231        self.assertArgSizeInArg(NSString.getCharacters_range_, 0, 1)
232
233        self.assertResultIsBOOL(NSString.isEqualToString_)
234        self.assertResultIsBOOL(NSString.hasPrefix_)
235        self.assertResultIsBOOL(NSString.hasSuffix_)
236        self.assertResultIsBOOL(NSString.boolValue)
237        self.assertArgIsOut(NSString.getLineStart_end_contentsEnd_forRange_, 0)
238        self.assertArgIsOut(NSString.getLineStart_end_contentsEnd_forRange_, 1)
239        self.assertArgIsOut(NSString.getLineStart_end_contentsEnd_forRange_, 2)
240        self.assertArgIsOut(NSString.getParagraphStart_end_contentsEnd_forRange_, 0)
241        self.assertArgIsOut(NSString.getParagraphStart_end_contentsEnd_forRange_, 1)
242        self.assertArgIsOut(NSString.getParagraphStart_end_contentsEnd_forRange_, 2)
243        self.assertArgIsBOOL(NSString.dataUsingEncoding_allowLossyConversion_, 1)
244        self.assertResultIsBOOL(NSString.canBeConvertedToEncoding_)
245        self.assertResultIsNullTerminated(NSString.cStringUsingEncoding_)
246        self.assertResultHasType(NSString.cStringUsingEncoding_, b'^v')
247        self.assertResultIsBOOL(NSString.getCString_maxLength_encoding_)
248        self.assertArgHasType(NSString.getCString_maxLength_encoding_, 0, b'o^v')
249        self.assertArgSizeInArg(NSString.getCString_maxLength_encoding_, 0, 1)
250
251        self.assertResultIsBOOL(NSString.getBytes_maxLength_usedLength_encoding_options_range_remainingRange_)
252        self.assertArgHasType(NSString.getBytes_maxLength_usedLength_encoding_options_range_remainingRange_, 0, b'o^v')
253        self.assertArgSizeInArg(NSString.getBytes_maxLength_usedLength_encoding_options_range_remainingRange_, 0, (1,2))
254        self.assertArgIsOut(NSString.getBytes_maxLength_usedLength_encoding_options_range_remainingRange_, 2)
255        self.assertArgIsOut(NSString.getBytes_maxLength_usedLength_encoding_options_range_remainingRange_, 6)
256
257        self.assertResultHasType(NSString.UTF8String, b'^' + objc._C_CHAR_AS_TEXT)
258        self.assertResultIsNullTerminated(NSString.UTF8String)
259        self.assertResultIsNullTerminated(NSString.availableStringEncodings)
260
261        self.assertArgHasType(NSString.initWithCharactersNoCopy_length_freeWhenDone_, 0, b'n^' + objc._C_UNICHAR)
262        self.assertArgSizeInArg(NSString.initWithCharactersNoCopy_length_freeWhenDone_, 0, 1)
263        self.assertArgIsBOOL(NSString.initWithCharactersNoCopy_length_freeWhenDone_, 2)
264        self.assertArgHasType(NSString.initWithCharacters_length_, 0, b'n^' + objc._C_UNICHAR)
265        self.assertArgSizeInArg(NSString.initWithCharacters_length_, 0, 1)
266        self.assertArgHasType(NSString.initWithUTF8String_, 0, b'n^' + objc._C_CHAR_AS_TEXT)
267        self.assertArgIsNullTerminated(NSString.initWithUTF8String_, 0)
268        self.assertArgIsPrintf(NSString.initWithFormat_, 0)
269        self.assertArgIsPrintf(NSString.initWithFormat_locale_, 0)
270
271        o = NSString.alloc()
272        self.assertArgIsIn(o.initWithBytes_length_encoding_, 0)
273        self.assertArgSizeInArg(o.initWithBytes_length_encoding_, 0, 1)
274        o = o.init()
275        self.assertArgIsIn(NSString.initWithBytesNoCopy_length_encoding_freeWhenDone_, 0)
276        self.assertArgSizeInArg(NSString.initWithBytesNoCopy_length_encoding_freeWhenDone_, 0, 1)
277        self.assertArgIsBOOL(NSString.initWithBytesNoCopy_length_encoding_freeWhenDone_, 3)
278
279        self.assertArgHasType(NSString.stringWithCharacters_length_, 0, b'n^' + objc._C_UNICHAR)
280        self.assertArgSizeInArg(NSString.stringWithCharacters_length_, 0, 1)
281        self.assertArgHasType(NSString.stringWithUTF8String_, 0, b'n^' + objc._C_CHAR_AS_TEXT)
282        self.assertArgIsNullTerminated(NSString.stringWithUTF8String_, 0)
283        self.assertArgIsPrintf(NSString.stringWithFormat_, 0)
284        self.assertArgIsPrintf(NSString.localizedStringWithFormat_, 0)
285
286        self.assertArgHasType(NSString.initWithCString_encoding_, 0, b'n^t')
287        self.assertArgIsNullTerminated(NSString.initWithCString_encoding_, 0)
288        self.assertArgHasType(NSString.stringWithCString_encoding_, 0, b'n^t')
289        self.assertArgIsNullTerminated(NSString.stringWithCString_encoding_, 0)
290
291        self.assertArgIsOut(NSString.initWithContentsOfURL_encoding_error_, 2)
292        self.assertArgIsOut(NSString.initWithContentsOfFile_encoding_error_, 2)
293        self.assertArgIsOut(NSString.stringWithContentsOfURL_encoding_error_, 2)
294        self.assertArgIsOut(NSString.stringWithContentsOfFile_encoding_error_, 2)
295
296        self.assertArgIsOut(NSString.initWithContentsOfURL_usedEncoding_error_, 1)
297        self.assertArgIsOut(NSString.initWithContentsOfURL_usedEncoding_error_, 2)
298        self.assertArgIsOut(NSString.initWithContentsOfFile_usedEncoding_error_, 1)
299        self.assertArgIsOut(NSString.initWithContentsOfFile_usedEncoding_error_, 2)
300        self.assertArgIsOut(NSString.stringWithContentsOfURL_usedEncoding_error_, 1)
301        self.assertArgIsOut(NSString.stringWithContentsOfURL_usedEncoding_error_, 2)
302        self.assertArgIsOut(NSString.stringWithContentsOfFile_usedEncoding_error_, 1)
303        self.assertArgIsOut(NSString.stringWithContentsOfFile_usedEncoding_error_, 2)
304
305        self.assertResultIsBOOL(NSString.writeToURL_atomically_encoding_error_)
306        self.assertArgIsBOOL(NSString.writeToURL_atomically_encoding_error_, 1)
307        self.assertArgIsOut(NSString.writeToURL_atomically_encoding_error_, 3)
308        self.assertResultIsBOOL(NSString.writeToFile_atomically_encoding_error_)
309        self.assertArgIsBOOL(NSString.writeToFile_atomically_encoding_error_, 1)
310        self.assertArgIsOut(NSString.writeToFile_atomically_encoding_error_, 3)
311
312        self.assertArgIsPrintf(NSMutableString.appendFormat_, 0)
313
314        self.assertResultHasType(NSString.cString, b'^t')
315        self.assertResultIsNullTerminated(NSString.cString)
316        self.assertResultHasType(NSString.lossyCString, b'^t')
317        self.assertResultIsNullTerminated(NSString.lossyCString)
318
319        self.assertArgHasType(NSString.getCString_maxLength_, 0, b'o^v')
320        self.assertArgSizeInArg(NSString.getCString_maxLength_, 0, 1)
321
322        self.assertArgHasType(NSString.getCString_maxLength_range_remainingRange_, 0, b'o^v')
323        self.assertArgSizeInArg(NSString.getCString_maxLength_range_remainingRange_, 0, 1)
324        self.assertArgIsOut(NSString.getCString_maxLength_range_remainingRange_, 3)
325
326        self.assertResultIsBOOL(NSString.writeToFile_atomically_)
327        self.assertArgIsBOOL(NSString.writeToFile_atomically_, 1)
328        self.assertResultIsBOOL(NSString.writeToURL_atomically_)
329        self.assertArgIsBOOL(NSString.writeToURL_atomically_, 1)
330
331        self.assertArgHasType(NSString.initWithCStringNoCopy_length_freeWhenDone_, 0, b'n^v')
332        self.assertArgSizeInArg(NSString.initWithCStringNoCopy_length_freeWhenDone_, 0, 1)
333        self.assertArgIsBOOL(NSString.initWithCStringNoCopy_length_freeWhenDone_, 2)
334        self.assertArgHasType(NSString.initWithCString_length_, 0, b'n^v')
335        self.assertArgSizeInArg(NSString.initWithCString_length_, 0, 1)
336        self.assertArgHasType(NSString.initWithCString_, 0, b'n^v')
337        self.assertArgIsNullTerminated(NSString.initWithCString_, 0)
338
339        self.assertArgHasType(NSString.stringWithCString_length_, 0, b'n^v')
340        self.assertArgSizeInArg(NSString.stringWithCString_length_, 0, 1)
341        self.assertArgHasType(NSString.stringWithCString_, 0, b'n^v')
342        self.assertArgIsNullTerminated(NSString.stringWithCString_, 0)
343
344    @min_os_level('10.6')
345    def testConstants10_6(self):
346        self.assertEqual(NSStringEnumerationByLines, 0)
347        self.assertEqual(NSStringEnumerationByParagraphs, 1)
348        self.assertEqual(NSStringEnumerationByComposedCharacterSequences, 2)
349        self.assertEqual(NSStringEnumerationByWords, 3)
350        self.assertEqual(NSStringEnumerationBySentences, 4)
351        self.assertEqual(NSStringEnumerationReverse, 1 << 8)
352        self.assertEqual(NSStringEnumerationSubstringNotRequired, 1 << 9)
353        self.assertEqual(NSStringEnumerationLocalized, 1 << 10)
354
355    @min_os_level('10.6')
356    def testMethods10_6(self):
357        self.assertArgHasType(NSString.enumerateSubstringsInRange_options_usingBlock_, 0,
358                NSRange.__typestr__)
359        self.assertArgIsBlock(NSString.enumerateSubstringsInRange_options_usingBlock_, 2, b'v@'+NSRange.__typestr__+NSRange.__typestr__+b'o^'+objc._C_NSBOOL)
360        self.assertArgIsBlock(NSString.enumerateLinesUsingBlock_, 0, b'v@o^'+objc._C_NSBOOL)
361
362
363
364if __name__ == '__main__':
365    main()
366