{-| Description: Copyright: (c) 2020 Samuel May License: MPL-2.0 Maintainer: ag.eitilt@gmail.com Stability: experimental Portability: portable -} module Test.Willow.Property.Encoding.GB ( tests ) where import qualified Hedgehog as H import qualified Hedgehog.Gen as H.G import qualified Hedgehog.Range as H.R import Web.Willow.Common.Encoding import Test.Willow.Property.Common tests :: H.Group tests = packGroup "Web.Willow.Common.Encoding.GB" -- Single byte tests handled in "unit" due to limited number [ decodeEndOfStream , decodeTwoByteInvalid , decodeThreeByteInvalid , decodeFourByteInvalid , decodeOneByteLookup , decodeTwoByteLookup , decodeFourByteLookup ] decodeEndOfStream :: Test decodeEndOfStream = packTest "incomplete character" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] first <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE second <- H.forAll . H.G.word8 $ H.R.linear 0x30 0x39 third <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE checkEndOfStream enc [first, second, third] decodeTwoByteInvalid :: Test decodeTwoByteInvalid = packTest "invalid second byte" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] first <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE second <- H.forAll $ H.G.choice [ H.G.word8 $ H.R.linear 0x00 0x2F , H.G.word8 $ H.R.linear 0x3A 0xFE , H.G.constant 0xFF ] let check = if second <= 0x7F then checkInvalid else checkInvalidAll check enc [first, second] decodeThreeByteInvalid :: Test decodeThreeByteInvalid = packTest "invalid third byte" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] first <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE second <- H.forAll . H.G.word8 $ H.R.linear 0x30 0x39 third <- H.forAll $ H.G.choice [ H.G.word8 $ H.R.linear 0x00 0x80 , H.G.constant 0xFF ] checkInvalid enc [first, second, third] decodeFourByteInvalid :: Test decodeFourByteInvalid = packTest "invalid fourth byte" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] first <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE second <- H.forAll . H.G.word8 $ H.R.linear 0x30 0x39 third <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE fourth <- H.forAll $ H.G.choice [ H.G.word8 $ H.R.linear 0x00 0x2F , H.G.word8 $ H.R.linear 0x3A 0xFE , H.G.constant 0xFF ] checkInvalid enc [first, second, third, fourth] decodeOneByteLookup :: Test decodeOneByteLookup = packTest "one-byte sequence" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] first <- H.forAll $ H.G.choice [ H.G.word8 $ H.R.linear 0x00 0x80 , H.G.constant 0xFF ] checkTrailing enc [first] decodeTwoByteLookup :: Test decodeTwoByteLookup = packTest "two-byte sequence" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] first <- H.forAll . H.G.word8 $ H.R.linear 0x81 0xFE second <- H.forAll . H.G.choice $ map H.G.word8 [ H.R.linear 0x40 0x7E , H.R.linear 0x80 0xFE ] if second <= 0x7F then checkTrailing enc [first, second] else checkTrailingAll enc [first, second] decodeFourByteLookup :: Test decodeFourByteLookup = packTest "four-byte sequence" $ do enc <- H.forAll $ H.G.element [Gbk, Gb18030] (first, second, third, fourth) <- H.forAll $ H.G.choice [ do b1 <- H.G.word8 $ H.R.linear 0x81 0xFE b2 <- H.G.word8 $ H.R.linear 0x30 0x39 b3 <- H.G.word8 $ H.R.linear 0x81 0xFE b4 <- H.G.word8 $ H.R.linear 0x30 0x39 return (b1, b2, b3, b4) , do -- null range between 39419 and 189000 b1 <- H.G.word8 $ H.R.linear 0x84 0xE9 let (l2, h2) = case b1 of 0x84 -> (0x31, 0x39) _ -> (0x30, 0x39) b2 <- H.G.word8 $ H.R.linear l2 h2 let l3 = case (b1, b2) of (0x84, 0x31) -> 0xA4 _ -> 0x81 b3 <- H.G.word8 $ H.R.linear l3 0xFE let (l4, h4) = case (b1, b2, b3) of (0x84, 0x31, 0xA4) -> (0x39, 0x39) (0xE9, 0x39, 0xFE) -> (0x30, 0x38) _ -> (0x30, 0x39) b4 <- H.G.word8 $ H.R.linear l4 h4 return (b1, b2, b3, b4) , do -- null range above 1237575 b1 <- H.G.word8 $ H.R.linear 0xE3 0xFE let l2 = case b1 of 0xE3 -> 0x32 _ -> 0x30 b2 <- H.G.word8 $ H.R.linear l2 0x39 let l3 = case (b1, b2) of (0xE3, 0x32) -> 0x9A _ -> 0x81 b3 <- H.G.word8 $ H.R.linear l3 0xFE let l4 = case (b1, b2, b3) of (0xE3, 0x32, 0x9A) -> 0x36 _ -> 0x30 b4 <- H.G.word8 $ H.R.linear l4 0x39 return (b1, b2, b3, b4) ] checkTrailingAll enc [first, second, third, fourth]