1from PyObjCTools.TestSupport import * 2import objc 3import re 4import sys 5import operator 6import os 7 8try: 9 long 10except NameError: 11 long = int 12 13 14from Foundation import * 15 16PLIST=b"""\ 17<?xml version="1.0" encoding="UTF-8"?> 18<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 19<plist version="1.0"> 20<dict> 21\t<key>bool</key> 22\t<true/> 23\t<key>plain</key> 24\t<integer>1</integer> 25</dict> 26</plist> 27""".decode('latin1') 28 29def stripDocType(val): 30 """ 31 Strip non-significant information. This is needed because the proplists 32 on MacOS X 10.1 are slightly different from the ones on MacOS X 10.2 ( 33 different DOCTYPE and version). 34 """ 35 r = re.sub(b'<!DOCTYPE [^>]*>'.decode('ascii'), b'<!DOCTYPE>'.decode('ascii'), val) 36 return r.replace(b'version="0.9"'.decode('ascii'), b'version="1.0"'.decode('ascii')) 37 38 39class TestNSNumber( TestCase ): 40 def testSimple(self): 41 self.assertEqual(NSNumber.numberWithFloat_(1.0), 1,0) 42 self.assertEqual(NSNumber.numberWithInt_(1), 1) 43 self.assertEqual(NSNumber.numberWithFloat_(-0.5), -0.5) 44 self.assertEqual(NSNumber.numberWithInt_(-4), -4) 45 self.assertEqual(NSNumber.numberWithInt_(0), 0) 46 self.assertEqual(NSNumber.numberWithFloat_(0.0), 0.0) 47 48 def testReadOnly(self): 49 n = NSNumber.numberWithFloat_(1.2) 50 self.assertRaises(AttributeError, setattr, n, 'foo', 2) 51 52 n = NSNumber.numberWithInt_(1) 53 self.assertRaises(AttributeError, setattr, n, 'foo', 2) 54 55 n = NSNumber.numberWithLongLong_(2**32 + 2) 56 self.assertRaises(AttributeError, setattr, n, 'foo', 2) 57 58 def testUseAsBasicType(self): 59 lstValue = list(range(0, 20, 2)) 60 for idx, v in enumerate(lstValue): 61 self.assertEqual(v, lstValue[NSNumber.numberWithInt_(idx)]) 62 self.assertEqual(v, lstValue[NSNumber.numberWithLong_(idx)]) 63 self.assertEqual(v, lstValue[NSNumber.numberWithLongLong_(idx)]) 64 65 self.assertRaises(TypeError, operator.getitem, lstValue, 66 NSNumber.numberWithFloat_(2.0)) 67 68 def testUnsignedIssues(self): 69 # NSNumber stores unsigned numbers as signed numbers 70 # This is a bug in Cocoa... (RADAR #4007594), fixed in 10.5 71 if sdkForPython() is not None and sdkForPython() < (10, 5): 72 self.assertEqual(NSNumber.numberWithUnsignedInt_(2**31), 73 -(2**31)) 74 else: 75 self.assertEqual(NSNumber.numberWithUnsignedInt_(2**31), 76 (2**31)) 77 78 def testMethods(self): 79 v = NSNumber.numberWithUnsignedInt_(2**31) 80 81 self.assertEqual(v.unsignedIntValue(), 2**31) 82 self.assertEqual(v.intValue(), -(2**31)) 83 84 v = NSNumber.numberWithInt_(10) 85 self.assertEqual(v.doubleValue(), float(10)) 86 87 def testMath(self): 88 Xs = list(range(10, 40, 3)) 89 Ys = list(range(-12, 44, 5)) 90 91 self.assertTrue(0 not in Ys) 92 self.assertTrue(0 not in Xs) 93 94 for x in Xs: 95 for y in Ys: 96 Nx = NSNumber.numberWithInt_(x) 97 Ny = NSNumber.numberWithInt_(y) 98 99 self.assertEqual(x + y, Nx + Ny) 100 self.assertEqual(x - y, Nx - Ny) 101 self.assertEqual(x * y, Nx * Ny) 102 self.assertEqual(x / y, Nx / Ny) 103 self.assertEqual(x % y, Nx % Ny) 104 self.assertEqual(x ** y, Nx ** Ny) 105 106 Nx = NSNumber.numberWithFloat_(x+0.5) 107 Ny = NSNumber.numberWithFloat_(y+0.5) 108 109 self.assertEqual((x+0.5) + (y+0.5), Nx + Ny) 110 self.assertEqual((x+0.5) - (y+0.5), Nx - Ny) 111 self.assertEqual((x+0.5) * (y+0.5), Nx * Ny) 112 self.assertEqual((x+0.5) / (y+0.5), Nx / Ny) 113 self.assertEqual((x+0.5) % (y+0.5), Nx % Ny) 114 self.assertEqual((x+0.5) ** (y+0.5), Nx ** Ny) 115 116 Nx = NSNumber.numberWithLongLong_(x) 117 Ny = NSNumber.numberWithLongLong_(y) 118 119 self.assertEqual(long(x) + long(y), Nx + Ny) 120 self.assertEqual(long(x) - long(y), Nx - Ny) 121 self.assertEqual(long(x) * long(y), Nx * Ny) 122 self.assertEqual(long(x) / long(y), Nx / Ny) 123 self.assertEqual(long(x) % long(y), Nx % Ny) 124 self.assertEqual(long(x) ** long(y), Nx ** Ny) 125 126 127 def testTyping(self): 128 # Thanks to some tricks and a cooperating Python runtime, 129 # NSNumber "instances" seem to be subclasses of both NSNumber and 130 # the corresponding Python number type. 131 # 132 133 n = NSNumber.numberWithInt_(10) 134 self.assertIsInstance(n, (int, long)) 135 self.assertIsInstance(n, NSNumber) 136 137 n = NSNumber.numberWithUnsignedInt_(10) 138 self.assertIsInstance(n, (int, long)) 139 self.assertIsInstance(n, NSNumber) 140 141 n = NSNumber.numberWithLong_(10) 142 self.assertIsInstance(n, (int, long)) 143 self.assertIsInstance(n, NSNumber) 144 145 n = NSNumber.numberWithUnsignedLong_(10) 146 self.assertIsInstance(n, (int, long)) 147 self.assertIsInstance(n, NSNumber) 148 149 n = NSNumber.numberWithLongLong_(2**32 * 1024) 150 self.assertEqual(n, 2**32 * 1024) 151 self.assertIsInstance(n, (int, long)) 152 self.assertIsInstance(n, NSNumber) 153 154 n = NSNumber.numberWithUnsignedLongLong_(2**32 + 100) 155 self.assertEqual(n, 2**32 + 100) 156 self.assertIsInstance(n, (int, long)) 157 self.assertIsInstance(n, NSNumber) 158 159 n = NSNumber.numberWithFloat_(10) 160 self.assertIsInstance(n, float) 161 self.assertIsInstance(n, NSNumber) 162 163 n = NSNumber.numberWithDouble_(10) 164 self.assertIsInstance(n, float) 165 self.assertIsInstance(n, NSNumber) 166 167 168if objc.platform == 'MACOSX': 169 class TestPropList (TestCase): 170 #Test if numbers are stored properly in property-list. The most 171 #important part of the testcase are boolean values. 172 # 173 # NOTE: GNUstep uses the old NeXT property lists, and these tests 174 # will fail. 175 176 def testPropertyList1(self): 177 d = NSMutableDictionary.dictionary() 178 179 # Python 2.3 only... 180 d[b'plain'.decode('ascii')] = 1 181 d[b'bool'.decode('ascii')] = objc.YES 182 183 self.assertEqual(d.writeToFile_atomically_( 184 b"/tmp/pyobjctest.plist".decode('ascii'), 0), 1) 185 186 fd = open(b'/tmp/pyobjctest.plist'.decode('ascii'), 'rb') 187 data = fd.read().decode('utf8') 188 fd.close() 189 190 self.assertEqual(stripDocType(data), stripDocType(PLIST)) 191 192 def testPropertyList2(self): 193 d = NSMutableDictionary.dictionary() 194 195 d[b'plain'.decode('ascii')] = NSNumber.numberWithLong_(1) 196 d[b'bool'.decode('ascii')] = NSNumber.numberWithBool_(1) 197 198 self.assertEqual(d.writeToFile_atomically_( 199 b"/tmp/pyobjctest.plist".decode('ascii'), 0), 1) 200 201 fd = open(b'/tmp/pyobjctest.plist'.decode('ascii'), 'rb') 202 data = fd.read().decode('utf8') 203 fd.close() 204 205 self.assertEqual(stripDocType(data), stripDocType(PLIST)) 206 207class TestDecimalNumber (TestCase): 208 def testProxy (self): 209 one = NSDecimalNumber.decimalNumberWithString_(b"1.00".decode('ascii')) 210 self.assertIsInstance(one, NSDecimalNumber) 211 212 two = NSDecimalNumber.decimalNumberWithString_(b"2.00".decode('ascii')) 213 self.assertIsInstance(two, NSDecimalNumber) 214 215 three = NSDecimalNumber.decimalNumberWithString_(b"3.00".decode('ascii')) 216 self.assertIsInstance(three, NSDecimalNumber) 217 218 six = NSDecimalNumber.decimalNumberWithString_(b"6.00".decode('ascii')) 219 self.assertIsInstance(six, NSDecimalNumber) 220 221 one_half = NSDecimalNumber.decimalNumberWithString_(b"0.50".decode('ascii')) 222 self.assertIsInstance(one_half, NSDecimalNumber) 223 224 225 self.assertEqual(one + two, three) 226 self.assertEqual(three - one, two) 227 self.assertEqual(three * two, six) 228 self.assertEqual(one / two, one_half) 229 self.assertEqual(three // two, one) 230 231 if sys.version_info[0] > 2: 232 self.assertEqual(round(three / two), one) 233 self.assertEqual(round(one / two, 1), one_half) 234 235 236 237if __name__ == '__main__': 238 main( ) 239