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