packages feed

bits-conduit-0.2.0.0: test.hs

{-# LANGUAGE OverloadedStrings, ViewPatterns #-}

import Control.Monad.Identity
import Data.Bits
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.Conduit
import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.List as CL
import Data.Word
import Test.Hspec.HUnit ()
import Test.Hspec.QuickCheck
import Test.Hspec.Monadic
import Test.HUnit

import Data.Conduit.Bits

main :: IO ()
main = hspec $ do
  describe "decoder" $ do
    it "decodes empty sequence" $ do
      a <- yield S.empty =$= decodeBits $$ CL.consume
      [] @=? a

    prop "decodes bits" $ \bs ->
      let a = runIdentity $ yield (S.pack bs) =$= decodeBits $$ CL.consume
      in decodeNaive bs == a

  describe "encoder" $ do
    it "encodes empty sequence" $ do
      a <- CL.sourceNull =$= encodeBits $$ CB.take maxBound
      L.empty @=? a

    prop "encodes bits" $ \bs ->
      let a = runIdentity $ CL.sourceList bs =$= encodeBits $$ CB.take maxBound
      in L.pack (encodeNaive bs) == a

decodeNaive :: [Word8] -> [Bool]
decodeNaive = concatMap f where
  f c = map (\i -> testBit c i) [0..7 :: Int]

encodeNaive :: [Bool] -> [Word8]
encodeNaive [] = []
encodeNaive (splitAt 8 -> (cur, next)) =
  let c = foldl (.|.) 0 (zipWith (\i b -> if b then bit i else 0) [0..] cur)
  in c : encodeNaive next