typed-encoding-0.3.0.0: test/Test/Bc/ASCIISpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fwarn-unused-imports #-}
-- | Verified backward compatibility of ASCII encoder changes in v0.3
module Test.Bc.ASCIISpec where
import qualified Data.TypedEncoding.Instances.Restriction.ASCII as ASCII
import Data.TypedEncoding.Common.Class.Util.StringConstraints
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.List as L
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy.Char8 as BL8
import Data.Char
import Control.Arrow
import Test.QuickCheck.Instances.ByteString ()
import Test.QuickCheck.Instances.Text ()
import Test.QuickCheck
import Test.QuickCheck.Property
import Test.Hspec
equivalProperty :: Eq str => (str -> Either NonAsciiChar str) -> (str -> Either NonAsciiChar str) -> str -> Property
equivalProperty alg1 alg2 str = property $ liftBool (alg1 str == alg2 str)
forwardCompatible :: (Char8Find str, Eq str) => (str -> Either NonAsciiChar str) -> str -> Property
forwardCompatible = equivalProperty newImpl
type NonAsciiChar = ASCII.NonAsciiChar
oldImplS = oldEncodeImpl L.partition L.head L.null
oldImplT = oldEncodeImpl T.partition T.head T.null
oldImplTL = oldEncodeImpl TL.partition TL.head TL.null
oldImplB = oldEncodeImpl (\p -> B8.filter p &&& B8.filter (not . p)) B8.head B8.null
oldImplBL = oldEncodeImpl (\p -> BL8.filter p &&& BL8.filter (not . p)) BL8.head BL8.null
newImpl :: Char8Find str => str -> Either NonAsciiChar str
newImpl = ASCII.encImpl
oldEncodeImpl ::
((Char -> Bool) -> a -> (a, a))
-> (a -> Char)
-> (a -> Bool)
-> a
-> Either NonAsciiChar a
oldEncodeImpl partitionf headf nullf t =
let (tascii, nonascii) = partitionf isAscii t
in if nullf nonascii
then Right tascii
else Left . ASCII.NonAsciiChar $ headf nonascii
spec :: Spec
spec =
describe "ASCII backward compapatibilty check" $ do
it "String" $ property $ forwardCompatible oldImplS
it "Text" $ property $ forwardCompatible oldImplT
it "Lazy.Text" $ property $ forwardCompatible oldImplTL
it "ByteString" $ property $ forwardCompatible oldImplB
it "Lazy.ByteString" $ property $ forwardCompatible oldImplBL
runSpec :: IO ()
runSpec = hspec spec