base32-0.4: test/Internal.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PackageImports #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- |
-- Module : Main
-- Copyright : (c) 2019-2023 Emily Pillmore
-- License : BSD-style
--
-- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>
-- Stability : Experimental
-- Portability : portable
--
-- This module contains internal test harnesses for `base32`
--
module Internal
( Harness(..)
, TextHarness(..)
, b32
, lb32
, sb32
, t32
, tl32
, ts32
, tt32
, ttl32
, tts32
) where
import Test.QuickCheck hiding (label)
import Data.Text
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base32 as B32
import qualified Data.ByteString.Base32.Hex as B32H
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Lazy.Base32 as BL32
import qualified Data.ByteString.Lazy.Base32.Hex as BL32H
import qualified Data.ByteString.Short as SBS
import qualified Data.ByteString.Short.Base32 as BS32
import qualified Data.ByteString.Short.Base32.Hex as BS32H
import qualified Data.Text as T
import qualified Data.Text.Encoding.Base32 as T32
import qualified Data.Text.Encoding.Base32.Hex as T32H
import Data.Text.Encoding.Base32.Error
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding.Base32 as TL32
import qualified Data.Text.Lazy.Encoding.Base32.Hex as TL32H
import qualified Data.Text.Short as TS
import qualified Data.Text.Short.Encoding.Base32 as TS32
import qualified Data.Text.Short.Encoding.Base32.Hex as TS32H
-- ------------------------------------------------------------------ --
-- Test Harnesses
-- | This class provides the generic API definition for
-- the base32 std alphabet
--
data Harness bs = Harness
{ label :: String
, encode :: bs -> bs
, encodeNopad :: bs -> bs
, encodeHex :: bs -> bs
, encodeHexNopad :: bs -> bs
, decode :: bs -> Either Text bs
, decodeHex :: bs -> Either Text bs
, decodePad :: bs -> Either Text bs
, decodeHexPad :: bs -> Either Text bs
, decodeNopad :: bs -> Either Text bs
, decodeHexNopad :: bs -> Either Text bs
, correct :: bs -> Bool
, correctHex :: bs -> Bool
, validate :: bs -> Bool
, validateHex :: bs -> Bool
}
b32 :: Harness BS.ByteString
b32 = Harness
{ label = "ByteString"
, encode = B32.encodeBase32'
, encodeNopad = B32.encodeBase32Unpadded'
, decode = B32.decodeBase32
, decodePad = B32.decodeBase32Padded
, decodeNopad = B32.decodeBase32Unpadded
, correct = B32.isBase32
, validate = B32.isValidBase32
, encodeHex = B32H.encodeBase32'
, encodeHexNopad = B32H.encodeBase32Unpadded'
, decodeHex = B32H.decodeBase32
, decodeHexPad = B32H.decodeBase32Padded
, decodeHexNopad = B32H.decodeBase32Unpadded
, correctHex = B32H.isBase32Hex
, validateHex = B32H.isValidBase32Hex
}
lb32 :: Harness LBS.ByteString
lb32 = Harness
{ label = "Lazy ByteString"
, encode = BL32.encodeBase32'
, encodeNopad = BL32.encodeBase32Unpadded'
, decode = BL32.decodeBase32
, decodePad = BL32.decodeBase32Padded
, decodeNopad = BL32.decodeBase32Unpadded
, correct = BL32.isBase32
, validate = BL32.isValidBase32
, encodeHex = BL32H.encodeBase32'
, encodeHexNopad = BL32H.encodeBase32Unpadded'
, decodeHex = BL32H.decodeBase32
, decodeHexPad = BL32H.decodeBase32Padded
, decodeHexNopad = BL32H.decodeBase32Unpadded
, correctHex = BL32H.isBase32Hex
, validateHex = BL32H.isValidBase32Hex
}
sb32 :: Harness SBS.ShortByteString
sb32 = Harness
{ label = "Short ByteString"
, encode = BS32.encodeBase32'
, encodeNopad = BS32.encodeBase32Unpadded'
, decode = BS32.decodeBase32
, decodePad = BS32.decodeBase32Padded
, decodeNopad = BS32.decodeBase32Unpadded
, correct = BS32.isBase32
, validate = BS32.isValidBase32
, encodeHex = BS32H.encodeBase32'
, encodeHexNopad = BS32H.encodeBase32Unpadded'
, decodeHex = BS32H.decodeBase32
, decodeHexPad = BS32H.decodeBase32Padded
, decodeHexNopad = BS32H.decodeBase32Unpadded
, correctHex = BS32H.isBase32Hex
, validateHex = BS32H.isValidBase32Hex
}
t32 :: Harness T.Text
t32 = Harness
{ label = "Text"
, encode = T32.encodeBase32
, encodeNopad = T32.encodeBase32Unpadded
, decode = T32.decodeBase32
, decodePad = T32.decodeBase32Padded
, decodeNopad = T32.decodeBase32Unpadded
, correct = T32.isBase32
, validate = T32.isValidBase32
, encodeHex = T32H.encodeBase32
, encodeHexNopad = T32H.encodeBase32Unpadded
, decodeHex = T32H.decodeBase32
, decodeHexPad = T32H.decodeBase32Padded
, decodeHexNopad = T32H.decodeBase32Unpadded
, correctHex = T32H.isBase32Hex
, validateHex = T32H.isValidBase32Hex
}
tl32 :: Harness TL.Text
tl32 = Harness
{ label = "Lazy Text"
, encode = TL32.encodeBase32
, encodeNopad = TL32.encodeBase32Unpadded
, decode = TL32.decodeBase32
, decodePad = TL32.decodeBase32Padded
, decodeNopad = TL32.decodeBase32Unpadded
, correct = TL32.isBase32
, validate = TL32.isValidBase32
, encodeHex = TL32H.encodeBase32
, encodeHexNopad = TL32H.encodeBase32Unpadded
, decodeHex = TL32H.decodeBase32
, decodeHexPad = TL32H.decodeBase32Padded
, decodeHexNopad = TL32H.decodeBase32Unpadded
, correctHex = TL32H.isBase32Hex
, validateHex = TL32H.isValidBase32Hex
}
ts32 :: Harness TS.ShortText
ts32 = Harness
{ label = "Short Lazy Text"
, encode = TS32.encodeBase32
, encodeNopad = TS32.encodeBase32Unpadded
, decode = TS32.decodeBase32
, decodePad = TS32.decodeBase32Padded
, decodeNopad = TS32.decodeBase32Unpadded
, correct = TS32.isBase32
, validate = TS32.isValidBase32
, encodeHex = TS32H.encodeBase32
, encodeHexNopad = TS32H.encodeBase32Unpadded
, decodeHex = TS32H.decodeBase32
, decodeHexPad = TS32H.decodeBase32Padded
, decodeHexNopad = TS32H.decodeBase32Unpadded
, correctHex = TS32H.isBase32Hex
, validateHex = TS32H.isValidBase32Hex
}
-- -------------------------------------------------------------------- --
-- Text-specific harness
data TextHarness bs cs = TextHarness
{ decodeWith_ :: forall err. (bs -> Either err cs) -> bs -> Either (Base32Error err) cs
, decodePaddedWith_ :: forall err. (bs -> Either err cs) -> bs -> Either (Base32Error err) cs
, decodeUnpaddedWith_ :: forall err. (bs -> Either err cs) -> bs -> Either (Base32Error err) cs
, decodeHexWith_ :: forall err. (bs -> Either err cs) -> bs -> Either (Base32Error err) cs
, decodeHexPaddedWith_ :: forall err. (bs -> Either err cs) -> bs -> Either (Base32Error err) cs
, decodeHexUnpaddedWith_ :: forall err. (bs -> Either err cs) -> bs -> Either (Base32Error err) cs
}
tt32 :: TextHarness BS.ByteString Text
tt32 = TextHarness
{ decodeWith_ = T32.decodeBase32With
, decodePaddedWith_ = T32.decodeBase32PaddedWith
, decodeUnpaddedWith_ = T32.decodeBase32UnpaddedWith
, decodeHexWith_ = T32H.decodeBase32With
, decodeHexPaddedWith_ = T32H.decodeBase32PaddedWith
, decodeHexUnpaddedWith_ = T32H.decodeBase32UnpaddedWith
}
ttl32 :: TextHarness LBS.ByteString TL.Text
ttl32 = TextHarness
{ decodeWith_ = TL32.decodeBase32With
, decodePaddedWith_ = TL32.decodeBase32PaddedWith
, decodeUnpaddedWith_ = TL32.decodeBase32UnpaddedWith
, decodeHexWith_ = TL32H.decodeBase32With
, decodeHexPaddedWith_ = TL32H.decodeBase32PaddedWith
, decodeHexUnpaddedWith_ = TL32H.decodeBase32UnpaddedWith
}
tts32 :: TextHarness SBS.ShortByteString TS.ShortText
tts32 = TextHarness
{ decodeWith_ = TS32.decodeBase32With
, decodePaddedWith_ = TS32.decodeBase32PaddedWith
, decodeUnpaddedWith_ = TS32.decodeBase32UnpaddedWith
, decodeHexWith_ = TS32H.decodeBase32With
, decodeHexPaddedWith_ = TS32H.decodeBase32PaddedWith
, decodeHexUnpaddedWith_ = TS32H.decodeBase32UnpaddedWith
}
-- ------------------------------------------------------------------ --
-- Quickcheck instances
instance Arbitrary BS.ByteString where
arbitrary = BS.pack <$> arbitrary
shrink xs = BS.pack <$> shrink (BS.unpack xs)
instance CoArbitrary BS.ByteString where
coarbitrary = coarbitrary . BS.unpack
instance Arbitrary LBS.ByteString where
arbitrary = LBS.pack <$> arbitrary
shrink xs = LBS.pack <$> shrink (LBS.unpack xs)
instance CoArbitrary LBS.ByteString where
coarbitrary = coarbitrary . LBS.unpack
instance Arbitrary SBS.ShortByteString where
arbitrary = SBS.pack <$> arbitrary
shrink xs = SBS.pack <$> shrink (SBS.unpack xs)
instance CoArbitrary SBS.ShortByteString where
coarbitrary = coarbitrary . SBS.unpack
instance Arbitrary T.Text where
arbitrary = T.pack . getUnicodeString <$> arbitrary
shrink xs = T.pack . getUnicodeString <$> shrink (UnicodeString $ T.unpack xs)
instance Arbitrary TL.Text where
arbitrary = TL.pack . getUnicodeString <$> arbitrary
shrink xs = TL.pack . getUnicodeString <$> shrink (UnicodeString $ TL.unpack xs)
instance CoArbitrary T.Text where
coarbitrary = coarbitrary . T.unpack
instance CoArbitrary TL.Text where
coarbitrary = coarbitrary . TL.unpack
instance Arbitrary TS.ShortText where
arbitrary = TS.fromText <$> arbitrary
shrink xs = TS.fromText <$> shrink (TS.toText xs)
instance CoArbitrary TS.ShortText where
coarbitrary = coarbitrary . TS.toText