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
10class TestNSDecimal (TestCase):
11    def testConstants(self):
12        self.assertEquals(NSRoundPlain, 0)
13        self.assertEquals(NSRoundDown, 1)
14        self.assertEquals(NSRoundUp, 2)
15        self.assertEquals(NSRoundBankers, 3)
16
17        self.assertEquals(NSCalculationNoError, 0)
18        self.assertEquals(NSCalculationLossOfPrecision, 1)
19        self.assertEquals(NSCalculationUnderflow, 2)
20        self.assertEquals(NSCalculationOverflow, 3)
21        self.assertEquals(NSCalculationDivideByZero, 4)
22
23        self.assertEquals(NSDecimalMaxSize, 8)
24        self.assertEquals(NSDecimalNoScale, (2**15)-1)
25
26    def testCreation(self):
27        o = NSDecimal(u"1.25")
28        self.assert_(isinstance(o, NSDecimal))
29        self.assertEquals(str(o), u"1.25")
30
31        o = NSDecimal(12345, -2, objc.YES)
32        self.assert_(isinstance(o, NSDecimal))
33        self.assertEquals(str(o), u"-123.45")
34
35        o = NSDecimal()
36        self.assert_(isinstance(o, NSDecimal))
37        self.assert_(str(o) in (u"0", u"0.0"))
38
39        o = NSDecimal(1234)
40        self.assert_(isinstance(o, NSDecimal))
41        self.assertEquals(str(o), u"1234")
42
43        o = NSDecimal(-1234)
44        self.assert_(isinstance(o, NSDecimal))
45        self.assertEquals(str(o), u"-1234")
46
47        o = NSDecimal(long(1234))
48        self.assert_(isinstance(o, NSDecimal))
49        self.assertEquals(str(o), u"1234")
50
51        o = NSDecimal(long(-1234))
52        self.assert_(isinstance(o, NSDecimal))
53        self.assertEquals(str(o), u"-1234")
54
55        o = NSDecimal(1L << 64 - 1)
56
57        # Explicit conversion is supported, but might not do
58        # what a naive user expects...
59        o = NSDecimal(1.1)
60        self.assert_(isinstance(o, NSDecimal))
61        self.assertEquals(str(o), repr(1.1))
62
63        self.assertRaises(OverflowError, NSDecimal, 1L << 128)
64        self.assertRaises(OverflowError, NSDecimal, -1L << 128)
65
66    def testFunction(self):
67        o = NSDecimal(u"1.5")
68        p = NSDecimal(12345, -2, objc.YES)
69        r = NSDecimal(u"-121.95")
70        q = NSDecimal()
71
72        NSDecimalAdd(q, o, p, NSRoundPlain)
73
74        self.assertEquals(str(q), str(r))
75
76        v = NSDecimalIsNotANumber(o)
77        self.failUnless(v is False)
78
79        v = NSDecimal()
80        NSDecimalCopy(v, o)
81        self.failUnlessEqual(str(v), str(o))
82
83        NSDecimalCompact(v)
84
85        i = NSDecimalCompare(o, p)
86        self.failUnlessIsInstance(i, (int, long))
87
88        NSDecimalRound(v, o, 0, NSRoundBankers)
89        self.failUnlessEqual(str(v), '2')
90
91        t = NSDecimalNormalize(v, o, NSRoundBankers)
92        self.failUnlessEqual(t, NSCalculationNoError)
93        self.failUnlessEqual(str(v), '2.0')
94
95        t = NSDecimalPower(v, o, 3, NSRoundBankers)
96        self.failUnlessEqual(t, NSCalculationNoError)
97        self.failUnlessEqual(str(v), '3.375')
98
99        t = NSDecimalString(v, None)
100        self.failUnlessEqual(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.assertEquals(o.as_int(), 1234)
127
128        o = NSDecimal(u"1.5")
129        self.assertEquals(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
143class TestNSDecimalNumber (TestCase):
144    def testCreation1(self):
145        o = NSDecimalNumber.decimalNumberWithString_(u"1.1234")
146        self.assertEquals(o.description(), u"1.1234")
147
148        p = o.decimalValue()
149        self.assert_(isinstance(p, NSDecimal))
150        self.assertEquals(str(p), u"1.1234")
151
152    def testCreation2(self):
153        p = NSDecimal(u"1.1234")
154        o = NSDecimalNumber.decimalNumberWithDecimal_(p)
155        self.assertEquals(o.description(), u"1.1234")
156
157    def testCreation3(self):
158        p = NSDecimal(u"1.1234")
159        o = NSDecimalNumber.alloc().initWithDecimal_(p)
160        self.assertEquals(o.description(), u"1.1234")
161
162class NSDecimalOperators (TestCase):
163    def testCoerce(self):
164        r = NSDecimal(1)
165
166        v = coerce(r, r)
167        self.assertEquals(v, (r, r))
168
169        v = coerce(r, 2)
170        self.assertEquals(v, (r, NSDecimal(2)))
171
172        v = coerce(2, r)
173        self.assertEquals(v, (NSDecimal(2), r))
174
175        v = coerce(r, sys.maxint+2)
176        self.assertEquals(v, (r, NSDecimal(sys.maxint+2)))
177
178        v = coerce(sys.maxint+2, r)
179        self.assertEquals(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.assertEquals(v, (NSDecimal(4), r))
185
186        v = coerce(r, t)
187        self.assertEquals(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.assertEquals(o+p, r)
211        self.assertEquals(o+P, r)
212        self.assertEquals(O+p, r)
213        self.assertEquals(o+2, r)
214        self.assertEquals(o+2L, r)
215        self.assertEquals(p+1, r)
216        self.assertEquals(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.assertEquals(o-p, r)
240        self.assertEquals(O-p, r)
241        self.assertEquals(o-P, r)
242        self.assertEquals(o-2, r)
243        self.assertEquals(o-2L, r)
244        self.assertEquals(1-p, r)
245        self.assertEquals(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.assertEquals(o*p, r)
268        self.assertEquals(O*p, r)
269        self.assertEquals(o*P, r)
270        self.assertEquals(o*3, r)
271        self.assertEquals(o*3L, r)
272        self.assertEquals(2*p, r)
273        self.assertEquals(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.assertEquals(o/p, r)
290        self.assertEquals(O/p, r)
291        self.assertEquals(o/P, r)
292        self.assertEquals(o/3, r)
293        self.assertEquals(o/3L, r)
294        self.assertEquals(2/p, r)
295        self.assertEquals(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.assertEquals(+o, o)
305        self.assertEquals(+p, p)
306
307    def testNegative(self):
308        o = NSDecimal(2)
309        p = NSDecimal(-2)
310
311        self.assertEquals(-o, p)
312        self.assertEquals(-p, o)
313
314    def testAbs(self):
315        o = NSDecimal(2)
316        p = NSDecimal(-2)
317
318        self.assertEquals(abs(o), o)
319        self.assertEquals(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.assertEquals(o, r)
358
359        o = NSDecimal(1)
360        o += P
361        self.assertEquals(o, r)
362
363        o = NSDecimal(1)
364        o += 2
365        self.assertEquals(o, r)
366
367        o = NSDecimal(1)
368        o += 2L
369        self.assertEquals(o, r)
370
371        o = 1
372        o += p
373        self.assertEquals(o, r)
374
375        o = 1L
376        o += p
377        self.assertEquals(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.assertEquals(o, r)
406
407        o = NSDecimal(1)
408        o -= P
409        self.assertEquals(o, r)
410
411
412        o = NSDecimal(1)
413        o -= 2
414        self.assertEquals(o, r)
415
416        o = NSDecimal(1)
417        o -= 2
418        self.assertEquals(o, r)
419
420        o = 1
421        o -= p
422        self.assertEquals(o, r)
423
424        o = 1
425        o -= p
426        self.assertEquals(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.assertEquals(o, r)
441
442        o = NSDecimal(2)
443        o *= P
444        self.assertEquals(o, r)
445
446        o = NSDecimal(2)
447        o *= 3
448        self.assertEquals(o, r)
449
450        o = NSDecimal(2)
451        o *= 3L
452        self.assertEquals(o, r)
453
454        o = 2
455        o *= p
456        self.assertEquals(o, r)
457
458        o = 2L
459        o *= p
460        self.assertEquals(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.assertEquals(o, r)
475
476        o = NSDecimal(2)
477        o /= P
478        self.assertEquals(o, r)
479
480        o = NSDecimal(2)
481        o /= 3
482        self.assertEquals(o, r)
483
484        o = NSDecimal(2)
485        o /= 3L
486        self.assertEquals(o, r)
487
488        o = 2
489        o /= p
490        self.assertEquals(o, r)
491
492        o = 2L
493        o /= p
494        self.assertEquals(o, r)
495
496class 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.assertEquals((o+p), r)
504        self.assertEquals((o+2), r)
505        self.assertEquals((o+2L), r)
506        self.assertEquals((1+p), r)
507        self.assertEquals((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.assertEquals((o-p), r)
522        self.assertEquals((o-2), r)
523        self.assertEquals((o-2L), r)
524        self.assertEquals((1-p), r)
525        self.assertEquals((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.assertEquals((o*p), r)
537        self.assertEquals((o*3), r)
538        self.assertEquals((o*3L), r)
539        self.assertEquals((2*p), r)
540        self.assertEquals((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.assertEquals((o/p), r)
552        self.assertEquals((o/3), r)
553        self.assertEquals((o/3L), r)
554        self.assertEquals((2/p), r)
555        self.assertEquals((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.assertEquals((+o), o.decimalValue())
565        self.assertEquals((+p), p.decimalValue())
566
567    def testNegative(self):
568        o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
569        p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
570
571        self.assertEquals((-o), p.decimalValue())
572        self.assertEquals((-p), o.decimalValue())
573
574    def testAbs(self):
575        o = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(2))
576        p = NSDecimalNumber.decimalNumberWithDecimal_(NSDecimal(-2))
577
578        self.assertEquals(abs(o), o.decimalValue())
579        self.assertEquals(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