on master help sign in
Add tests for shifts, and fix a bug exposed along the way.
793e0b3Bryan O'Sullivan
Data/Text/UnsafeShift.hs+2−2
@@ -33,14 +33,14 @@ class UnsafeShift a where
33
33
34instance UnsafeShift Word16 where
34instance UnsafeShift Word16 where
35 {-# INLINE shiftL #-}
35 {-# INLINE shiftL #-}
36− shiftL (W16# x#) (I# i#) = W16# (x# `uncheckedShiftL#` i#)
36+ shiftL (W16# x#) (I# i#) = W16# (narrow16Word# (x# `uncheckedShiftL#` i#))
37
37
38 {-# INLINE shiftR #-}
38 {-# INLINE shiftR #-}
39 shiftR (W16# x#) (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
39 shiftR (W16# x#) (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
40
40
41instance UnsafeShift Word32 where
41instance UnsafeShift Word32 where
42 {-# INLINE shiftL #-}
42 {-# INLINE shiftL #-}
43− shiftL (W32# x#) (I# i#) = W32# (x# `uncheckedShiftL#` i#)
43+ shiftL (W32# x#) (I# i#) = W32# (narrow32Word# (x# `uncheckedShiftL#` i#))
44
44
45 {-# INLINE shiftR #-}
45 {-# INLINE shiftR #-}
46 shiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
46 shiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
tests/Properties.hs+27−1
@@ -5,12 +5,13 @@
5import Test.QuickCheck
5import Test.QuickCheck
6import Text.Show.Functions ()
6import Text.Show.Functions ()
7
7
8+import qualified Data.Bits as Bits (shiftL, shiftR)
8import Data.Char (chr, isLower, isSpace, isUpper, ord)
9import Data.Char (chr, isLower, isSpace, isUpper, ord)
9import Data.Monoid (Monoid(..))
10import Data.Monoid (Monoid(..))
10import Data.String (fromString)
11import Data.String (fromString)
11import Debug.Trace (trace)
12import Debug.Trace (trace)
12import Control.Arrow ((***), second)
13import Control.Arrow ((***), second)
13−import Data.Word (Word8)
14+import Data.Word (Word8, Word16, Word32)
14import qualified Data.Text as T
15import qualified Data.Text as T
15import qualified Data.Text.Compat as C
16import qualified Data.Text.Compat as C
16import qualified Data.Text.Lazy as TL
17import qualified Data.Text.Lazy as TL
@@ -20,6 +21,7 @@ import qualified Data.Text.Fusion as S
20import qualified Data.Text.Fusion.Common as S
21import qualified Data.Text.Fusion.Common as S
21import qualified Data.Text.Lazy.Encoding as EL
22import qualified Data.Text.Lazy.Encoding as EL
22import qualified Data.Text.Lazy.Fusion as SL
23import qualified Data.Text.Lazy.Fusion as SL
24+import qualified Data.Text.UnsafeShift as U
23import qualified Data.List as L
25import qualified Data.List as L
24import System.IO.Unsafe (unsafePerformIO)
26import System.IO.Unsafe (unsafePerformIO)
25import Test.Framework (defaultMain, testGroup)
27import Test.Framework (defaultMain, testGroup)
@@ -465,6 +467,21 @@ sf_zipWith p c s = (L.zipWith c (L.filter p s) . L.filter p) `eqP` (unpackS . S
465t_zipWith c s = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
467t_zipWith c s = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
466tl_zipWith c s = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
468tl_zipWith c s = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
467
469
470+-- Bit shifts.
471+shiftL w = forAll (choose (0,width-1)) $ \k -> Bits.shiftL w k == U.shiftL w k
472+ where width = round (log (fromIntegral m) / log 2)
473+ (m,_) = (maxBound, m == w)
474+shiftR w = forAll (choose (0,width-1)) $ \k -> Bits.shiftR w k == U.shiftR w k
475+ where width = round (log (fromIntegral m) / log 2)
476+ (m,_) = (maxBound, m == w)
477+
478+shiftL_Int = shiftL :: Int -> Property
479+shiftL_Word16 = shiftL :: Word16 -> Property
480+shiftL_Word32 = shiftL :: Word32 -> Property
481+shiftR_Int = shiftR :: Int -> Property
482+shiftR_Word16 = shiftR :: Word16 -> Property
483+shiftR_Word32 = shiftR :: Word32 -> Property
484+
468-- Regression tests.
485-- Regression tests.
469s_filter_eq s = S.filter p t == S.streamList (filter p s)
486s_filter_eq s = S.filter p t == S.streamList (filter p s)
470 where p = (/= S.last t)
487 where p = (/= S.last t)
@@ -799,5 +816,14 @@ tests = [
799
816
800 testGroup "regressions" [
817 testGroup "regressions" [
801 testProperty "s_filter_eq" s_filter_eq
818 testProperty "s_filter_eq" s_filter_eq
819+ ],
820+
821+ testGroup "shifts" [
822+ testProperty "shiftL_Int" shiftL_Int,
823+ testProperty "shiftL_Word16" shiftL_Word16,
824+ testProperty "shiftL_Word32" shiftL_Word32,
825+ testProperty "shiftR_Int" shiftR_Int,
826+ testProperty "shiftR_Word16" shiftR_Word16,
827+ testProperty "shiftR_Word32" shiftR_Word32
802 ]
828 ]
803 ]
829 ]
tests/QuickCheckUtils.hs+9−1
@@ -2,7 +2,7 @@
2
2
3module QuickCheckUtils where
3module QuickCheckUtils where
4
4
5−import Data.Word (Word8, Word16)
5+import Data.Word (Word8, Word16, Word32)
6import qualified Data.Text as T
6import qualified Data.Text as T
7import qualified Data.Text.Lazy as TL
7import qualified Data.Text.Lazy as TL
8import System.Random (Random(..), RandomGen)
8import System.Random (Random(..), RandomGen)
@@ -34,6 +34,14 @@ instance Arbitrary Word16 where
34 arbitrary = choose (minBound,maxBound)
34 arbitrary = choose (minBound,maxBound)
35 coarbitrary c = variant (fromEnum c `rem` 4)
35 coarbitrary c = variant (fromEnum c `rem` 4)
36
36
37+instance Random Word32 where
38+ randomR = integralRandomR
39+ random = randomR (minBound,maxBound)
40+
41+instance Arbitrary Word32 where
42+ arbitrary = choose (minBound,maxBound)
43+ coarbitrary c = variant (fromEnum c `rem` 4)
44+
37instance Arbitrary Char where
45instance Arbitrary Char where
38 arbitrary = oneof [choose ('\0','\55295'), choose ('\57344','\1114111')]
46 arbitrary = oneof [choose ('\0','\55295'), choose ('\57344','\1114111')]
39 coarbitrary c = variant (fromEnum c `rem` 4)
47 coarbitrary c = variant (fromEnum c `rem` 4)