1
1
module Test.Main where
2
2
3
+ import Prelude
3
4
import Control.Monad.Eff.Console (log )
5
+ import Data.Array (filter , range )
4
6
import Data.BigInt
5
- import Data.Maybe
7
+ import Data.Foldable (mconcat )
8
+ import Data.Maybe (Maybe (..))
6
9
import Data.Maybe.Unsafe (fromJust )
7
- import Prelude
8
- import Test.Assert
9
- import Test.QuickCheck
10
- import Test.QuickCheck.Arbitrary
11
- import Test.QuickCheck.Gen (chooseInt )
10
+ import Test.Assert (assert )
11
+ import Test.QuickCheck (quickCheck )
12
+ import Test.QuickCheck.Arbitrary (Arbitrary )
13
+ import Test.QuickCheck.Gen (Gen (..), chooseInt , arrayOf , elements )
12
14
import qualified Data.Int as Int
13
15
14
16
-- | Newtype with an Arbitrary instance that generates only small integers
@@ -20,6 +22,17 @@ instance arbitrarySmallInt :: Arbitrary SmallInt where
20
22
runSmallInt :: SmallInt -> Int
21
23
runSmallInt (SmallInt n) = n
22
24
25
+ -- | Arbitrary instance for BigInt
26
+ instance arbitraryBigInt :: Arbitrary BigInt where
27
+ arbitrary = do
28
+ n <- (fromJust <<< fromString) <$> digitString
29
+ op <- elements id [negate]
30
+ return (op n)
31
+ where digits :: Gen Int
32
+ digits = chooseInt 0 9
33
+ digitString :: Gen String
34
+ digitString = (mconcat <<< map show) <$> arrayOf digits
35
+
23
36
-- | Convert SmallInt to BigInt
24
37
fromSmallInt :: SmallInt -> BigInt
25
38
fromSmallInt = fromInt <<< runSmallInt
@@ -46,6 +59,7 @@ main = do
46
59
assert $ fromString " 2.1" == Nothing
47
60
assert $ fromString " 123456789" == Just (fromInt 123456789 )
48
61
assert $ fromString " 1e7" == Just (fromInt 10000000 )
62
+ quickCheck $ \a -> (fromString <<< toString) a == Just a
49
63
50
64
log " Parsing strings with a different base"
51
65
assert $ fromBase 2 " 100" == Just four
@@ -62,18 +76,26 @@ main = do
62
76
testBinary mod mod
63
77
testBinary div div
64
78
79
+ -- To test the multiplication, we need to make sure that Int does not overflow
80
+ quickCheck (\x y -> fromSmallInt x * fromSmallInt y == fromInt (runSmallInt x * runSmallInt y))
81
+
65
82
log " It should perform multiplications which would lead to imprecise results using Number"
66
83
assert $ Just (fromInt 333190782 * fromInt 1103515245 ) == fromString " 367681107430471590"
67
84
68
- -- To check the multiplication, we need to make sure that the Int does not overflow
69
- quickCheck (\x y -> fromSmallInt x * fromSmallInt y == fromInt (runSmallInt x * runSmallInt y))
70
-
71
- log " compare and (==) should be the same before and after converting to BigInt"
85
+ log " compare, (==), even, odd should be the same before and after converting to BigInt"
72
86
quickCheck (\x y -> compare x y == compare (fromInt x) (fromInt y))
73
87
quickCheck (\x y -> (fromSmallInt x == fromSmallInt y) == (runSmallInt x == runSmallInt y))
88
+ quickCheck (\x -> Int .even x == even (fromInt x))
89
+ quickCheck (\x -> Int .odd x == odd (fromInt x))
74
90
75
91
log " pow should perform integer exponentiation and yield 0 for negative exponents"
76
92
assert $ three `pow` four == fromInt 81
77
93
assert $ three `pow` -two == zero
78
94
assert $ three `pow` zero == one
79
95
assert $ zero `pow` zero == one
96
+
97
+ log " Prime numbers"
98
+ assert $ filter (prime <<< fromInt) (range 2 20 ) == [2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 ]
99
+
100
+ log " Absolute value"
101
+ quickCheck $ \x -> abs x == if x > zero then x else (-x)
0 commit comments