1#
2# Some tests for NSDecimal (C type) and NSDecimalNumber (Objective-C class)
3#
4from PyObjCTools.TestSupport import *
5from Foundation import *
6import operator
7import objc
8import sys
9
10if 0:
11    class TestNSDecimal (TestCase):
12        def testConstants(self):
13            self.assertEqual(NSRoundPlain, 0)
14            self.assertEqual(NSRoundDown, 1)
15            self.assertEqual(NSRoundUp, 2)
16            self.assertEqual(NSRoundBankers, 3)
17
18            self.assertEqual(NSCalculationNoError, 0)
19            self.assertEqual(NSCalculationLossOfPrecision, 1)
20            self.assertEqual(NSCalculationUnderflow, 2)
21            self.assertEqual(NSCalculationOverflow, 3)
22            self.assertEqual(NSCalculationDivideByZero, 4)
23
24            self.assertEqual(NSDecimalMaxSize, 8)
25            self.assertEqual(NSDecimalNoScale, (2**15)-1)
26
27        def testCreation(self):
28            o = NSDecimal(u"1.25")
29            self.assert_(isinstance(o, NSDecimal))
30            self.assertEqual(str(o), u"1.25")
31
32            o = NSDecimal(12345, -2, objc.YES)
33            self.assert_(isinstance(o, NSDecimal))
34            self.assertEqual(str(o), u"-123.45")
35
36            o = NSDecimal()
37            self.assert_(isinstance(o, NSDecimal))
38            self.assert_(str(o) in (u"0", u"0.0"))
39
40            o = NSDecimal(1234)
41            self.assert_(isinstance(o, NSDecimal))
42            self.assertEqual(str(o), u"1234")
43
44            o = NSDecimal(-1234)
45            self.assert_(isinstance(o, NSDecimal))
46            self.assertEqual(str(o), u"-1234")
47
48            o = NSDecimal(long(1234))
49            self.assert_(isinstance(o, NSDecimal))
50            self.assertEqual(str(o), u"1234")
51
52            o = NSDecimal(long(-1234))
53            self.assert_(isinstance(o, NSDecimal))
54            self.assertEqual(str(o), u"-1234")
55
56            o = NSDecimal(1L << 64 - 1)
57
58            # Explicit conversion is supported, but might not do
59            # what a naive user expects...
60            o = NSDecimal(1.1)
61            self.assert_(isinstance(o, NSDecimal))
62            self.assertEqual(str(o), repr(1.1))
63
64            self.assertRaises(OverflowError, NSDecimal, 1L << 128)
65            self.assertRaises(OverflowError, NSDecimal, -1L << 128)
66
67        def testFunction(self):
68            o = NSDecimal(u"1.5")
69            p = NSDecimal(12345, -2, objc.YES)
70            r = NSDecimal(u"-121.95")
71            q = NSDecimal()
72
73            NSDecimalAdd(q, o, p, NSRoundPlain)
74
75            self.assertEqual(str(q), str(r))
76
77            v = NSDecimalIsNotANumber(o)
78            self.assertIs(v, False)
79            v = NSDecimal()
80            NSDecimalCopy(v, o)
81            self.assertEqual(str(v), str(o))
82
83            NSDecimalCompact(v)
84
85            i = NSDecimalCompare(o, p)
86            self.assertIsInstance(i, (int, long))
87
88            NSDecimalRound(v, o, 0, NSRoundBankers)
89            self.assertEqual(str(v), '2')
90
91            t = NSDecimalNormalize(v, o, NSRoundBankers)
92            self.assertEqual(t, NSCalculationNoError)
93            self.assertEqual(str(v), '2.0')
94
95            t = NSDecimalPower(v, o, 3, NSRoundBankers)
96            self.assertEqual(t, NSCalculationNoError)
97            self.assertEqual(str(v), '3.375')
98
99            t = NSDecimalString(v, None)
100            self.assertEqual(t, u'3.375')
101
102
103        def testCompare(self):
104            small = NSDecimal(u"1")
105            small2 = NSDecimal(u"1")
106            large = NSDecimal(u"42")
107
108            self.assert_(small == small2)
109            self.assert_(not (small == large))
110            self.assert_(not (small != small2))
111            self.assert_(small < large)
112            self.assert_(not(large < small))
113            self.assert_(not(small < small))
114            self.assert_(small <= large)
115            self.assert_(small <= small)
116            self.assert_(not(large <= small))
117            self.assert_(large > small)
118            self.assert_(not(small > large))
119            self.assert_(not(large > large))
120            self.assert_(large >= small)
121            self.assert_(large >= large)
122            self.assert_(not(small >= large))
123
124        def testConversion(self):
125            o = NSDecimal(u"1234.44")
126            self.assertEqual(o.as_int(), 1234)
127
128            o = NSDecimal(u"1.5")
129            self.assertEqual(o.as_float(), 1.5)
130
131            self.assertRaises(TypeError, int, o)
132            self.assertRaises(TypeError, float, o)
133
134        def testCreateFromFloat(self):
135            o = NSDecimal(1.1)
136            self.assertAlmostEquals(o.as_float(), 1.1)
137
138        if not hasattr(TestCase, 'assertAlmostEquals'):
139            def assertAlmostEquals(self, val1, val2, eta=0.000001):
140                self.assert_(abs(val1 - val2) < eta)
141
142
143    class TestNSDecimalNumber (TestCase):
144        def testCreation1(self):
145            o = NSDecimalNumber.decimalNumberWithString_(u"1.1234")
146            self.assertEqual(o.description(), u"1.1234")
147
148            p = o.decimalValue()
149            self.assert_(isinstance(p, NSDecimal))
150            self.assertEqual(str(p), u"1.1234")
151
152        def testCreation2(self):
153            p = NSDecimal(u"1.1234")
154            o = NSDecimalNumber.decimalNumberWithDecimal_(p)
155            self.assertEqual(o.description(), u"1.1234")
156
157        def testCreation3(self):
158            p = NSDecimal(u"1.1234")
159            o = NSDecimalNumber.alloc().initWithDecimal_(p)
160            self.assertEqual(o.description(), u"1.1234")
161
162    class NSDecimalOperators (TestCase):
163        def testCoerce(self):
164            r = NSDecimal(1)
165
166            v = coerce(r, r)
167            self.assertEqual(v, (r, r))
168
169            v = coerce(r, 2)
170            self.assertEqual(v, (r, NSDecimal(2)))
171
172            v = coerce(2, r)
173            self.assertEqual(v, (NSDecimal(2), r))
174
175            v = coerce(r, sys.maxint+2)
176            self.assertEqual(v, (r, NSDecimal(sys.maxint+2)))
177
178            v = coerce(sys.maxint+2, r)
179            self.assertEqual(v, (NSDecimal(sys.maxint+2), r))
180
181            t = NSDecimal(4).__pyobjc_object__
182            self.assert_(isinstance(t, NSObject))
183            v = coerce(t, r)
184            self.assertEqual(v, (NSDecimal(4), r))
185
186            v = coerce(r, t)
187            self.assertEqual(v, (r, NSDecimal(4)))
188
189            self.assertRaises(TypeError, coerce, 1.0, r)
190            self.assertRaises(TypeError, coerce, r, 1.0)
191            self.assertRaises(TypeError, coerce, "1.0", r)
192            self.assertRaises(TypeError, coerce, r, "1.0")
193            self.assertRaises(TypeError, coerce, u"1.0", r)
194            self.assertRaises(TypeError, coerce, r, u"1.0")
195            self.assertRaises(TypeError, coerce, (), r)
196            self.assertRaises(TypeError, coerce, r, ())
197
198
199        def testAddition(self):
200            r = NSDecimal()
201            o = NSDecimal(1)
202            p = NSDecimal(2)
203
204            O = o.__pyobjc_object__
205            P = p.__pyobjc_object__
206            self.assert_(isinstance(P, NSObject))
207            self.assert_(isinstance(O, NSObject))
208
209            NSDecimalAdd(r, o, p, NSRoundPlain)
210            self.assertEqual(o+p, r)
211            self.assertEqual(o+P, r)
212            self.assertEqual(O+p, r)
213            self.assertEqual(o+2, r)
214            self.assertEqual(o+2L, r)
215            self.assertEqual(p+1, r)
216            self.assertEqual(1+p, r)
217
218            self.assertRaises(TypeError, operator.add, o, 1.2)
219            self.assertRaises(TypeError, operator.add, 1.2, o)
220            self.assertRaises(TypeError, operator.add, o, "1.2")
221            self.assertRaises(TypeError, operator.add, "1.2", o)
222            self.assertRaises(TypeError, operator.add, o, u"1.2")
223            self.assertRaises(TypeError, operator.add, u"1.2", o)
224            self.assertRaises(TypeError, operator.add, o, [])
225            self.assertRaises(TypeError, operator.add, [], o)
226
227        def testSubtraction(self):
228            r = NSDecimal()
229            o = NSDecimal(1)
230            p = NSDecimal(2)
231
232            P = p.__pyobjc_object__
233            O = o.__pyobjc_object__
234            self.assert_(isinstance(P, NSObject))
235            self.assert_(isinstance(O, NSObject))
236
237
238            NSDecimalSubtract(r, o, p, NSRoundPlain)
239            self.assertEqual(o-p, r)
240            self.assertEqual(O-p, r)
241            self.assertEqual(o-P, r)
242            self.assertEqual(o-2, r)
243            self.assertEqual(o-2L, r)
244            self.assertEqual(1-p, r)
245            self.assertEqual(1-p, r)
246
247            self.assertRaises(TypeError, operator.sub, o, 1.2)
248            self.assertRaises(TypeError, operator.sub, 1.2, o)
249            self.assertRaises(TypeError, operator.sub, o, "1.2")
250            self.assertRaises(TypeError, operator.sub, "1.2", o)
251            self.assertRaises(TypeError, operator.sub, o, u"1.2")
252            self.assertRaises(TypeError, operator.sub, u"1.2", o)
253            self.assertRaises(TypeError, operator.sub, o, ())
254            self.assertRaises(TypeError, operator.sub, (), o)
255
256        def testMultiplication(self):
257            r = NSDecimal()
258            o = NSDecimal(2)
259            p = NSDecimal(3)
260
261            P = p.__pyobjc_object__
262            O = o.__pyobjc_object__
263            self.assert_(isinstance(P, NSObject))
264            self.assert_(isinstance(O, NSObject))
265
266            NSDecimalMultiply(r, o, p, NSRoundPlain)
267            self.assertEqual(o*p, r)
268            self.assertEqual(O*p, r)
269            self.assertEqual(o*P, r)
270            self.assertEqual(o*3, r)
271            self.assertEqual(o*3L, r)
272            self.assertEqual(2*p, r)
273            self.assertEqual(2*p, r)
274
275            self.assertRaises(TypeError, operator.mul, o, 1.2)
276            self.assertRaises(TypeError, operator.mul, 1.2, o)
277
278        def testDivision(self):
279            r = NSDecimal()
280            o = NSDecimal(2)
281            p = NSDecimal(3)
282
283            P = p.__pyobjc_object__
284            O = o.__pyobjc_object__
285            self.assert_(isinstance(P, NSObject))
286            self.assert_(isinstance(O, NSObject))
287
288            NSDecimalDivide(r, o, p, NSRoundPlain)
289            self.assertEqual(o/p, r)
290            self.assertEqual(O/p, r)
291            self.assertEqual(o/P, r)
292            self.assertEqual(o/3, r)
293            self.assertEqual(o/3L, r)
294            self.assertEqual(2/p, r)
295            self.assertEqual(2/p, r)
296
297            self.assertRaises(TypeError, operator.div, o, 1.2)
298            self.assertRaises(TypeError, operator.div, 1.2, o)
299
300        def testPositive(self):
301            o = NSDecimal(2)
302            p = NSDecimal(-2)
303
304            self.assertEqual(+o, o)
305            self.assertEqual(+p, p)
306
307        def testNegative(self):
308            o = NSDecimal(2)
309            p = NSDecimal(-2)
310
311            self.assertEqual(-o, p)
312            self.assertEqual(-p, o)
313
314        def testAbs(self):
315            o = NSDecimal(2)
316            p = NSDecimal(-2)
317
318            self.assertEqual(abs(o), o)
319            self.assertEqual(abs(p), o)
320
321        def testBitwise(self):
322            o = NSDecimal(2)
323            p = NSDecimal(3)
324
325            self.assertRaises(TypeError, operator.and_, o, p)
326            self.assertRaises(TypeError, operator.or_, o, p)
327            self.assertRaises(TypeError, operator.not_, o, p)
328
329        def testPow(self):
330            o = NSDecimal(2)
331            p = NSDecimal(3)
332
333            self.assertRaises(TypeError, pow, o, p)
334            self.assertRaises(TypeError, pow, o, 2)
335            self.assertRaises(TypeError, pow, 2, o)
336
337        def testDivMod(self):
338            o = NSDecimal(2)
339            p = NSDecimal(3)
340
341            self.assertRaises(TypeError, divmod, o, p)
342            self.assertRaises(TypeError, divmod, o, 2)
343            self.assertRaises(TypeError, divmod, 2, o)
344
345        def testInplaceAddition(self):
346            r = NSDecimal()
347            o = NSDecimal(1)
348            p = NSDecimal(2)
349
350            P = p.__pyobjc_object__
351            self.assert_(isinstance(P, NSObject))
352
353            NSDecimalAdd(r, o, p, NSRoundPlain)
354
355            o = NSDecimal(1)
356            o += p
357            self.assertEqual(o, r)
358
359            o = NSDecimal(1)
360            o += P
361            self.assertEqual(o, r)
362
363            o = NSDecimal(1)
364            o += 2
365            self.assertEqual(o, r)
366
367            o = NSDecimal(1)
368            o += 2L
369            self.assertEqual(o, r)
370
371            o = 1
372            o += p
373            self.assertEqual(o, r)
374
375            o = 1L
376            o += p
377            self.assertEqual(o, r)
378
379            try:
380                o = 1.2
381                o += p
382                self.fail()
383            except TypeError:
384                pass
385
386            try:
387                o = NSDecimal(1)
388                o += 1.2
389                self.fail()
390            except TypeError:
391                pass
392
393        def testInplaceSubtraction(self):
394            r = NSDecimal()
395            o = NSDecimal(1)
396            p = NSDecimal(2)
397
398            P = p.__pyobjc_object__
399            self.assert_(isinstance(P, NSObject))
400
401            NSDecimalSubtract(r, o, p, NSRoundPlain)
402
403            o = NSDecimal(1)
404            o -= p
405            self.assertEqual(o, r)
406
407            o = NSDecimal(1)
408            o -= P
409            self.assertEqual(o, r)
410
411
412            o = NSDecimal(1)
413            o -= 2
414            self.assertEqual(o, r)
415
416            o = NSDecimal(1)
417            o -= 2
418            self.assertEqual(o, r)
419
420            o = 1
421            o -= p
422            self.assertEqual(o, r)
423
424            o = 1
425            o -= p
426            self.assertEqual(o, r)
427
428        def testInplaceMultiplication(self):
429            r = NSDecimal()
430            o = NSDecimal(2)
431            p = NSDecimal(3)
432
433            P = p.__pyobjc_object__
434            self.assert_(isinstance(P, NSObject))
435
436            NSDecimalMultiply(r, o, p, NSRoundPlain)
437
438            o = NSDecimal(2)
439            o *= p
440            self.assertEqual(o, r)
441
442            o = NSDecimal(2)
443            o *= P
444            self.assertEqual(o, r)
445
446            o = NSDecimal(2)
447            o *= 3
448            self.assertEqual(o, r)
449
450            o = NSDecimal(2)
451            o *= 3L
452            self.assertEqual(o, r)
453
454            o = 2
455            o *= p
456            self.assertEqual(o, r)
457
458            o = 2L
459            o *= p
460            self.assertEqual(o, r)
461
462        def testInplaceDivision(self):
463            r = NSDecimal()
464            o = NSDecimal(2)
465            p = NSDecimal(3)
466
467            P = p.__pyobjc_object__
468            self.assert_(isinstance(P, NSObject))
469
470            NSDecimalDivide(r, o, p, NSRoundPlain)
471
472            o = NSDecimal(2)
473            o /= p
474            self.assertEqual(o, r)
475
476            o = NSDecimal(2)
477            o /= P
478            self.assertEqual(o, r)
479
480            o = NSDecimal(2)
481            o /= 3
482            self.assertEqual(o, r)
483
484            o = NSDecimal(2)
485            o /= 3L
486            self.assertEqual(o, r)
487
488            o = 2
489            o /= p
490            self.assertEqual(o, r)
491
492            o = 2L
493            o /= p
494            self.assertEqual(o, r)
495
496    class NSDecimalNumberOperators (TestCase):
497        def testAddition(self):
498            r = NSDecimal()
499            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(1))
500            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
501
502            NSDecimalAdd(r, o.decimalValue(), p.decimalValue(), NSRoundPlain)
503            self.assertEqual((o+p), r)
504            self.assertEqual((o+2), r)
505            self.assertEqual((o+2L), r)
506            self.assertEqual((1+p), r)
507            self.assertEqual((1+p), r)
508
509            self.assertRaises(TypeError, operator.add, o, 1.2)
510            self.assertRaises(TypeError, operator.add, 1.2, o)
511
512            o = NSDecimalNumber.zero()
513            self.assertRaises(TypeError, operator.add, o, 1.2)
514
515        def testSubtraction(self):
516            r = NSDecimal()
517            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(1))
518            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
519
520            NSDecimalSubtract(r, o.decimalValue(), p.decimalValue(), NSRoundPlain)
521            self.assertEqual((o-p), r)
522            self.assertEqual((o-2), r)
523            self.assertEqual((o-2L), r)
524            self.assertEqual((1-p), r)
525            self.assertEqual((1-p), r)
526
527            self.assertRaises(TypeError, operator.sub, o, 1.2)
528            self.assertRaises(TypeError, operator.sub, 1.2, o)
529
530        def testMultiplication(self):
531            r = NSDecimal()
532            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
533            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(3))
534
535            NSDecimalMultiply(r, o.decimalValue(), p.decimalValue(), NSRoundPlain)
536            self.assertEqual((o*p), r)
537            self.assertEqual((o*3), r)
538            self.assertEqual((o*3L), r)
539            self.assertEqual((2*p), r)
540            self.assertEqual((2*p), r)
541
542            self.assertRaises(TypeError, operator.mul, o, 1.2)
543            self.assertRaises(TypeError, operator.mul, 1.2, o)
544
545        def testDivision(self):
546            r = NSDecimal()
547            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
548            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(3))
549
550            NSDecimalDivide(r, o.decimalValue(), p.decimalValue(), NSRoundPlain)
551            self.assertEqual((o/p), r)
552            self.assertEqual((o/3), r)
553            self.assertEqual((o/3L), r)
554            self.assertEqual((2/p), r)
555            self.assertEqual((2/p), r)
556
557            self.assertRaises(TypeError, operator.div, o, 1.2)
558            self.assertRaises(TypeError, operator.div, 1.2, o)
559
560        def testPositive(self):
561            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
562            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
563
564            self.assertEqual((+o), o.decimalValue())
565            self.assertEqual((+p), p.decimalValue())
566
567        def testNegative(self):
568            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
569            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
570
571            self.assertEqual((-o), p.decimalValue())
572            self.assertEqual((-p), o.decimalValue())
573
574        def testAbs(self):
575            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
576            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
577
578            self.assertEqual(abs(o), o.decimalValue())
579            self.assertEqual(abs(p), o.decimalValue())
580
581        def testBitwise(self):
582            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
583            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
584
585            self.assertRaises(TypeError, operator.and_, o, p)
586            self.assertRaises(TypeError, operator.or_, o, p)
587            self.assertRaises(TypeError, operator.not_, o, p)
588
589        def testPow(self):
590            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
591            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
592
593            self.assertRaises(TypeError, pow, o, p)
594            self.assertRaises(TypeError, pow, o, 2)
595            self.assertRaises(TypeError, pow, 2, o)
596
597        def testDivMod(self):
598            o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
599            p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
600
601            self.assertRaises(TypeError, divmod, o, p)
602            self.assertRaises(TypeError, divmod, o, 2)
603            self.assertRaises(TypeError, divmod, 2, o)
604
605
606if __name__ == "__main__":
607    main()
608