1from PyObjCTools.TestSupport import * 2import objc 3import array 4import sys 5 6from Foundation import * 7from PyObjCTest.testhelper import PyObjC_TestClass3 8 9rawBytes = b"a\x13b\x00cd\xFFef\xEFgh" 10otherBytes = array.array('b') 11otherBytes.fromstring('12345678901234567890' * 5) 12 13if sys.version_info[0] == 3: 14 buffer = memoryview 15 16try: 17 memoryview 18except NameError: 19 memoryview = None 20 21class TestNSData(TestCase): 22 def testMethods(self): 23 self.assertResultIsBOOL(NSData.writeToFile_atomically_) 24 self.assertArgIsBOOL(NSData.writeToFile_atomically_, 1) 25 self.assertResultIsBOOL(NSData.writeToURL_atomically_) 26 self.assertArgIsBOOL(NSData.writeToURL_atomically_, 1) 27 self.assertResultIsBOOL(NSData.writeToFile_options_error_) 28 self.assertArgIsOut(NSData.writeToFile_options_error_, 2) 29 self.assertResultIsBOOL(NSData.writeToURL_options_error_) 30 self.assertArgIsOut(NSData.writeToURL_options_error_, 2) 31 self.assertArgIsOut(NSData.dataWithContentsOfFile_options_error_, 2) 32 self.assertArgIsOut(NSData.dataWithContentsOfURL_options_error_, 2) 33 self.assertArgIsOut(NSData.initWithContentsOfFile_options_error_, 2) 34 self.assertArgIsOut(NSData.initWithContentsOfURL_options_error_, 2) 35 36 def testConstants(self): 37 self.assertEqual(NSMappedRead, 1) 38 self.assertEqual(NSUncachedRead, 2) 39 40 self.assertEqual(NSAtomicWrite, 1) 41 42 @min_os_level('10.6') 43 def testConstants10_6(self): 44 self.assertEqual(NSDataReadingMapped, 1<<0) 45 self.assertEqual(NSDataReadingUncached, 1<<1) 46 self.assertEqual(NSDataWritingAtomic, 1<<0) 47 self.assertEqual(NSDataSearchBackwards, 1<<0) 48 self.assertEqual(NSDataSearchAnchored, 1<<1) 49 50 @min_os_level('10.6') 51 def testMethods10_6(self): 52 self.assertResultHasType(NSData.rangeOfData_options_range_, NSRange.__typestr__) 53 self.assertArgHasType(NSData.rangeOfData_options_range_, 2, NSRange.__typestr__) 54 55 def assertDataContents(self, d1, d2, rawData): 56 self.assertEqual(len(d1), d1.length(), "d1: len() and -length didn't match.") 57 self.assertEqual(len(d1), len(rawData), "d1: len(<data>) and len(<input>) didn't match. %d vs %d"%(len(d1), len(rawData))) 58 self.assertEqual(len(d2), d2.length(), "d2: len() and -length didn't match.") 59 self.assertEqual(len(d2), len(rawData), "d2: len(<data>) and len(<input>) didn't match. %d vs %d"%(len(d2), len(rawData))) 60 61 def testDataWithBytes_length_(self): 62 # Test +dataWithBytes:length 63 data = NSData.dataWithBytes_length_(rawBytes, len(rawBytes)) 64 mutableData = NSMutableData.dataWithBytes_length_(rawBytes, len(rawBytes)) 65 self.assertDataContents(data, mutableData, rawBytes) 66 67 def testAppendBytes_length_(self): 68 self.assertArgIsIn(NSMutableData.appendBytes_length_, 0) 69 self.assertArgSizeInArg(NSMutableData.appendBytes_length_, 0, 1) 70 71 def testreplaceBytesInRange_withBytes_(self): 72 self.assertArgIsIn(NSMutableData.replaceBytesInRange_withBytes_, 1) 73 self.assertArgSizeInArg(NSMutableData.replaceBytesInRange_withBytes_, 1, 0) 74 75 def testreplaceBytesInRange_withBytes_length_(self): 76 self.assertArgIsIn(NSMutableData.replaceBytesInRange_withBytes_length_, 1) 77 self.assertArgSizeInArg(NSMutableData.replaceBytesInRange_withBytes_length_, 1, 2) 78 79 def testDataWithBytesNoCopy_length_freeWhenDone_(self): 80 data = NSData.dataWithBytesNoCopy_length_freeWhenDone_(rawBytes, len(rawBytes), False) 81 mutableData = NSMutableData.dataWithBytesNoCopy_length_freeWhenDone_(rawBytes, len(rawBytes), False) 82 self.assertDataContents(data, mutableData, rawBytes) 83 84 def testInitWithBytes_length_(self): 85 # Test -initWithBytes:length: 86 data = NSData.alloc().initWithBytes_length_(rawBytes, len(rawBytes)) 87 mutableData = NSMutableData.alloc().initWithBytes_length_(rawBytes, len(rawBytes)) 88 self.assertDataContents(data, mutableData, rawBytes) 89 90 def testInitWithBytesNoCopy_length_freeWhenDone_(self): 91 # Test -initWithBytesNoCopy:length: 92 data = NSData.alloc().initWithBytesNoCopy_length_freeWhenDone_(rawBytes, len(rawBytes), False) 93 mutableData = NSMutableData.alloc().initWithBytesNoCopy_length_freeWhenDone_(rawBytes, len(rawBytes), False) 94 self.assertDataContents(data, mutableData, rawBytes) 95 96 def testBytes(self): 97 # Test -bytes 98 data = NSData.alloc().initWithBytes_length_(rawBytes, len(rawBytes)) 99 bytesValue = data.bytes() 100 self.assertEqual(len(bytesValue), len(rawBytes), "bytes() and rawBytes not equal length.") 101 102 if sys.version_info[:2] <= (2,6): 103 self.assertEquals(buffer(rawBytes), bytesValue) 104 105 else: 106 self.assertEquals(rawBytes, bytesValue) 107 108 try: 109 bytesValue[3] = b'\xAE' 110 except TypeError, r: 111 if str(r).find('buffer is read-only') == 0: 112 pass 113 elif str(r).find('cannot modify read-only memory') == 0: 114 pass 115 else: 116 raise 117 118 def testMutableBytes(self): 119 # Test -mutableBytes 120 mutableData = NSMutableData.dataWithBytes_length_(rawBytes, len(rawBytes)) 121 mutableBytes = mutableData.mutableBytes() 122 for i in range(0, len(mutableBytes)): 123 mutableBytes[i] = otherBytes[i:i+1].tostring() 124 mutableBytes[1:8] = otherBytes[1:8].tostring() 125 126 try: 127 mutableBytes[2:10] = otherBytes[1:5].tostring() 128 except (TypeError, ValueError), r: 129 if str(r).find('right operand length must match slice length') == 0: 130 pass 131 elif 'cannot modify size of memoryview object' in str(r): 132 pass 133 else: 134 raise 135 136 def testVariousDataLengths(self): 137 # Test data of different lengths. 138 # 139 # Data of different lengths may be stored in different subclasses within the class cluster. 140 testFactor = range(1, 64) + [ 1000, 10000, 1000000] 141 for aFactor in testFactor: 142 bigRawBytes = b"1234567890" * aFactor 143 144 mutableData = NSMutableData.dataWithBytes_length_(bigRawBytes, len(bigRawBytes)) 145 data = NSData.dataWithBytes_length_(bigRawBytes, len(bigRawBytes)) 146 147 self.assertDataContents(data, mutableData, bigRawBytes) 148 149 mutableBytes = mutableData.mutableBytes() 150 bytes = data.bytes() 151 152 self.assertEqual(len(bytes), data.length()) 153 self.assertEqual(len(mutableBytes), mutableData.length()) 154 self.assertEqual(bytes, mutableBytes) 155 156 mutableBytes[0:len(mutableBytes)] = bytes[0:len(bytes)] 157 158 def testInitWithContents(self): 159 b, err = NSData.alloc().initWithContentsOfFile_options_error_( 160 "/etc/hosts", 0, None) 161 self.assertIsInstance(b, NSData) 162 self.assertIs(err, None) 163 b2, err = NSData.alloc().initWithContentsOfFile_options_error_( 164 "/etc/hosts.nosuchfile", 0, None) 165 self.assertIs(b2, None) 166 self.assertIsInstance(err, NSError) 167 url = NSURL.fileURLWithPath_isDirectory_('/etc/hosts', False) 168 b, err = NSData.alloc().initWithContentsOfURL_options_error_( 169 url, 0, None) 170 self.assertIsInstance(b, NSData) 171 self.assertIs(err, None) 172 url = NSURL.fileURLWithPath_isDirectory_('/etc/hosts.nosuchfile', False) 173 b2, err = NSData.alloc().initWithContentsOfURL_options_error_( 174 url, 0, None) 175 self.assertIs(b2, None) 176 self.assertIsInstance(err, NSError) 177class MyData (NSData): 178 def dataWithBytes_length_(self, bytes, length): 179 return ("data", bytes, length) 180 181BYTES="dummy bytes" 182class MyData2 (NSData): 183 def initWithBytes_length_(self, bytes, length): 184 return ("init", bytes, length) 185 186 def length(self): 187 return 42 188 189 def bytes(self): 190 return BYTES 191 192 193class MyData3 (NSData): 194 def initWithBytes_length_(self, bytes, length): 195 self._bytes = bytes 196 self._length = length 197 return self 198 199 def bytes(self): 200 return self._bytes 201 202 def length(self): 203 if hasattr(self, '_length'): 204 return self._length 205 return -1 206 207class MyData4 (NSData): 208 def initWithBytes_length_(self, bytes, length): 209 return self 210 211 def bytes(self): 212 return None 213 214 def length(self): 215 return -1 216 217class MyData5(NSData): 218 def initWithBytes_length_(self, bytes, length): 219 return self 220 221 def bytes(self): 222 raise ValueError, "No bytes available" 223 224 def length(self): 225 return -1 226 227 228 229class TestMyData (TestCase): 230 # 'initWithBytes:length:' and 'dataWithBytes:length:' have custom IMP's 231 def testData(self): 232 r = PyObjC_TestClass3.makeDataWithBytes_method_(MyData, 0) 233 self.assertEqual(r, ('data', b'hello world', 11)) 234 235 def testInit(self): 236 r = PyObjC_TestClass3.makeDataWithBytes_method_(MyData2, 1) 237 self.assertEqual(r, ('init', b'hello world', 11)) 238 239 def testBytes(self): 240 r = PyObjC_TestClass3.makeDataWithBytes_method_(MyData3, 1) 241 b = PyObjC_TestClass3.getBytes_(r) 242 243 # Check for memoryview 244 if isinstance(b.bytes(), memoryview): 245 self.assertEqual(b.bytes().tobytes(), b'hello world') 246 else: 247 self.assertEqual(bytes(b.bytes()), b'hello world') 248 249 self.assertEqual(b.getBytes_length_(None, 4), b'hell') 250 self.assertEqual(b.getBytes_range_(None, NSRange(2, 4)), b'llo ') 251 252 253 def testBytesNone(self): 254 b = PyObjC_TestClass3.makeDataWithBytes_method_(MyData4, 1) 255 self.assertEqual(b.bytes(), None) 256 257 def testBytesRaises(self): 258 b = PyObjC_TestClass3.makeDataWithBytes_method_(MyData5, 1) 259 self.assertRaises(ValueError, b.bytes) 260 261 262 263import array 264class TestBuffer(TestCase): 265 def testArray(self): 266 a = array.array('b', b'foo') 267 m = NSMutableData.dataWithData_(a) 268 self.assertEqual(a.tostring(), m[:]) 269 self.assert_(objc.repythonify(a) is a) 270 a.fromstring(m) 271 self.assertEqual(a.tostring(), b'foofoo') 272 m.appendData_(a) 273 self.assertEqual(m[:], b'foofoofoo') 274 m[3:6] = b'bar' 275 self.assertEqual(m[:], b'foobarfoo') 276 277 def testBuffer(self): 278 if sys.version_info[0] == 3: 279 b = b'foo' 280 else: 281 b = buffer('foo') 282 m = NSMutableData.dataWithData_(b) 283 self.assertEqual(b[:], m[:]) 284 self.assert_(objc.repythonify(b) is b) 285 self.assertEqual(buffer(m)[:], m[:]) 286 287 288class TestRegressions (TestCase): 289 def testDataStr(self): 290 if sys.version_info[0] == 2: 291 input = buffer("hello") 292 input_str = "hello" 293 else: 294 input = b"hello" 295 input_str = str(input) 296 297 buf = NSData.dataWithData_(input) 298 self.assertEquals(str(buf), input_str) 299 300 301if __name__ == '__main__': 302 main( ) 303