11module Test.Main where
22
3+ import Prelude
34import Control.Monad.Eff.Console (log )
5+ import Data.Array (filter , range )
46import Data.BigInt
5- import Data.Maybe
7+ import Data.Foldable (mconcat )
8+ import Data.Maybe (Maybe (..))
69import 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 )
1214import qualified Data.Int as Int
1315
1416-- | Newtype with an Arbitrary instance that generates only small integers
@@ -20,6 +22,17 @@ instance arbitrarySmallInt :: Arbitrary SmallInt where
2022runSmallInt :: SmallInt -> Int
2123runSmallInt (SmallInt n) = n
2224
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+
2336-- | Convert SmallInt to BigInt
2437fromSmallInt :: SmallInt -> BigInt
2538fromSmallInt = fromInt <<< runSmallInt
@@ -46,6 +59,7 @@ main = do
4659 assert $ fromString " 2.1" == Nothing
4760 assert $ fromString " 123456789" == Just (fromInt 123456789 )
4861 assert $ fromString " 1e7" == Just (fromInt 10000000 )
62+ quickCheck $ \a -> (fromString <<< toString) a == Just a
4963
5064 log " Parsing strings with a different base"
5165 assert $ fromBase 2 " 100" == Just four
@@ -62,18 +76,26 @@ main = do
6276 testBinary mod mod
6377 testBinary div div
6478
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+
6582 log " It should perform multiplications which would lead to imprecise results using Number"
6683 assert $ Just (fromInt 333190782 * fromInt 1103515245 ) == fromString " 367681107430471590"
6784
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"
7286 quickCheck (\x y -> compare x y == compare (fromInt x) (fromInt y))
7387 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))
7490
7591 log " pow should perform integer exponentiation and yield 0 for negative exponents"
7692 assert $ three `pow` four == fromInt 81
7793 assert $ three `pow` -two == zero
7894 assert $ three `pow` zero == one
7995 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