willow-0.1.0.0: test/Test/Willow/WebPlatformTests/Manual/Encoding/SingleByte.hs
{-|
Description: Emulating tests from @encoding/single-byte-decoder.js@
Copyright: (c) 2020 Samuel May
License: MPL-2.0
Maintainer: ag.eitilt@gmail.com
Stability: experimental
Portability: portable
-}
module Test.Willow.WebPlatformTests.Manual.Encoding.SingleByte
( tests
) where
import qualified Data.ByteString as BS
import qualified Data.Maybe as Y
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Read as T.R
import qualified Test.HUnit as U
import System.FilePath ( (</>), (<.>) )
import Test.HUnit ( (~:), (~?=), (@?) )
import Web.Willow.Common.Encoding
import Web.Willow.Common.Encoding.Labels
import Test.Willow.WebPlatformTests.Manual.CommonReader
tests :: IO U.Test
tests = do
charsets' <- charsets
return $ "single-byte-decoder.html" ~: U.TestList
[ "decoded charset matches index" ~: U.TestList $ map expectedCharsetDecode charsets'
, "encoded index is sane" ~: U.TestList $ map expectedCharsetEncode charsets'
, "encode-decode index roundtrips" ~: U.TestList $ map roundtrip charsets'
]
charsets :: IO [(Encoding, [Maybe Char])]
charsets = do
testFile <- dataFile $ "encoding" </> "single-byte-decoder" <.> "html"
f <- T.readFile testFile
let ls = filter (T.isPrefixOf $ T.pack " \"") $ T.lines f
is = map (T.split $ \c -> c == '[' || c == ']') ls
return $ Y.mapMaybe (\l -> extract l >>= repack) is
where extract (l:is:_) = Just (T.split (== '"') l !! 1, T.split (== ',') is)
extract _ = Nothing
toChar = either (const Nothing) (Just . toEnum . fst) . T.R.decimal
repack (enc, index) = case lookupEncoding enc of
Just enc' -> Just (enc', map Just ['\NUL'..'\DEL'] ++ map toChar index)
Nothing -> Nothing
--TODO: This is also supposed to check all labels ('someEncodings').
expectedCharsetDecode :: (Encoding, [Maybe Char]) -> U.Test
expectedCharsetDecode (enc, index) = show enc ~:
decodeEnc' enc (BS.pack [0x00..0xFF]) ~?= T.pack (map (Y.fromMaybe '\xFFFD') index)
--TODO: The below aren't actually part of the WPT; remove them once there's an
-- equivalent in Test.Willow.Unit.
expectedCharsetEncode :: (Encoding, [Maybe Char]) -> U.Test
expectedCharsetEncode (enc, index) = show enc ~: U.TestCase $ do
let bs = encodeEnc' enc . T.pack $ Y.catMaybes index
BS.length bs <= 0x100 @? "charset too long"
-- This doesn't check the encoded values are correct, but it does at least
-- make sure nothing's out of order.
snd (BS.foldl' (\(c, b) c' -> (c', b && c < c')) (0x00, True) $ BS.drop 1 bs)
@? "charset out of order"
roundtrip :: (Encoding, [Maybe Char]) -> U.Test
roundtrip (enc, index) = show enc ~:
decodeEnc' enc (encodeEnc' enc index') ~?= index'
where index' = T.pack $ Y.catMaybes index