packages feed

quickcheck-text (empty) → 0.1.0.0

raw patch · 7 files changed

+230/−0 lines, 7 filesdep +QuickCheckdep +basedep +binarysetup-changed

Dependencies added: QuickCheck, base, binary, bytestring, quickcheck-text, text

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Sharif Olorin++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,7 @@+# quickcheck-text++The usual Arbitrary instance for Text (in+[quickcheck-instances](https://hackage.haskell.org/package/quickcheck-instances))+only has single-byte instances and so isn't an ideal representation of+a valid UTF-8 character. This package has generators for one-, two-+and three-byte UTF-8 characters (all that are currently in use).
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ quickcheck-text.cabal view
@@ -0,0 +1,47 @@+name:                quickcheck-text+version:             0.1.0.0+synopsis:            Alternative arbitrary instance for Text+description:         The usual Arbitrary instance for Text+                     (in+                     <https://hackage.haskell.org/package/quickcheck-instances quickcheck-instances>) +                     only has single-byte+                     instances and so isn't an ideal representation of a valid UTF-8+                     character. This package has generators for one-, two- and three-byte+                     UTF-8 characters (all that are currently in use).+license:             MIT+license-file:        LICENSE+author:              Sharif Olorin+maintainer:          sio@tesser.org+copyright:           2015 Sharif Olorin+category:            Text+build-type:          Simple+cabal-version:       >=1.10+extra-source-files:  README.md++source-repository    head+  type:              git+  location:          git@github.com:olorin/quickcheck-instances.git++library+  exposed-modules:     Test.QuickCheck.Utf8+                       Data.Text.Arbitrary+  build-depends:       base >=4.7 && <5+                     , QuickCheck+                     , binary+                     , bytestring+                     , text+  hs-source-dirs:      src+  default-language:    Haskell2010+  ghc-options:         -Wall++test-suite properties+  hs-source-dirs:      test+  main-is:             properties.hs+  type:                exitcode-stdio-1.0+  default-language:    Haskell2010+  ghc-options:         -Wall+  build-depends:       base >=4.7 && <5+                     , QuickCheck+                     , bytestring+                     , quickcheck-text+                     , text
+ src/Data/Text/Arbitrary.hs view
@@ -0,0 +1,11 @@+module Data.Text.Arbitrary(+  Text()+) where++import           Data.Text++import           Test.QuickCheck+import           Test.QuickCheck.Utf8++instance Arbitrary Text where+  arbitrary = genValidUtf8
+ src/Test/QuickCheck/Utf8.hs view
@@ -0,0 +1,94 @@+module Test.QuickCheck.Utf8(+    genValidUtf8+  , utf8BS+  , genValidUtf81+  , utf8BS1+    -- * Generators for single characters+  , oneByte+  , twoByte+  , threeByte+) where++import           Control.Monad++import           Data.Binary.Builder+import           Data.Binary.Get++import           Data.ByteString     (ByteString)+import qualified Data.ByteString     as BS+import qualified Data.ByteString.Lazy     as BL+import           Data.Char+import           Data.Text           (Text)+import qualified Data.Text           as T+import           Data.Text.Encoding+import           Data.Text.Internal.Encoding.Utf8+import           Data.Word++import           Test.QuickCheck++-- |+-- Generate a possibly-empty valid UTF-8 'Text' value.+genValidUtf8 :: Gen Text+genValidUtf8 = fmap decodeUtf8 utf8BS++-- |+-- Generate a possibly-empty sequence of bytes which represent a valid+-- UTF-8 code point.+utf8BS :: Gen ByteString+utf8BS = fmap BS.concat $ elements symbolTypes  >>= listOf++-- |+-- Like 'genValidUtf8', but does not allow empty 'Text' values.+genValidUtf81 :: Gen Text+genValidUtf81 = fmap decodeUtf8 utf8BS1++-- |+-- Like 'utf8BS', but does not allow empty 'ByteString's.+utf8BS1 :: Gen ByteString+utf8BS1 = fmap BS.concat $ elements symbolTypes  >>= listOf1++symbolTypes :: [Gen ByteString]+symbolTypes = [ oneByte+              , twoByte+              , threeByte+              ]++inRange :: Int -> Int -> Gen Word8+inRange lo hi = fmap fromIntegral $ elements [lo..hi]++-- | Single-byte UTF-8 (i.e., a standard ASCII byte with a cleared MSB).+oneByte :: Gen ByteString+oneByte = fmap (BS.pack . return) $+  inRange 0 127 -- 0bbbbbbb++twoByte :: Gen ByteString+twoByte = do+  b1 <- inRange 0xC2 0xDF -- 110bbbbb+  b2 <- nonInitial+  return . buildUtf $ putBytes2 b1 b2++threeByte :: Gen ByteString+threeByte = do+  (b1, b2) <- oneof [b3_1, b3_2, b3_3, b3_4]+  b3 <- nonInitial+  return . buildUtf $ putBytes3 b1 b2 b3+ where+  b3_1 = (,) `fmap` return 0xE0 `ap` inRange 0xA0 0xBF++  b3_2 = (,) `fmap` inRange 0xE1 0xEC `ap` nonInitial++  b3_3 = (,) `fmap` return 0xED `ap` inRange 0x80 0x9F++  b3_4 = (,) `fmap` inRange 0xEE 0xEF `ap` nonInitial++buildUtf :: Builder -> ByteString +buildUtf = BS.concat . BL.toChunks . toLazyByteString++putBytes2 :: Word8 -> Word8 -> Builder+putBytes2 b1 b2 =  putCharUtf8 $ chr2 b1 b2++putBytes3 :: Word8 -> Word8 -> Word8 -> Builder+putBytes3 b1 b2 b3 =  putCharUtf8 $ chr3 b1 b2 b3++nonInitial :: Gen Word8+nonInitial = inRange 0x80 0xBF
+ test/properties.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE TemplateHaskell #-}++module Main where++import           Control.Monad++import           Data.Bits+import qualified Data.ByteString      as BS+import           Data.Text.Encoding++import           System.Exit++import           Test.QuickCheck+import           Test.QuickCheck.Utf8++prop_decodes_without_exception :: Property+prop_decodes_without_exception = forAll utf8BS $ \bs ->+  decodeUtf8 bs === decodeUtf8 bs++prop_oneByte_lsb :: Property+prop_oneByte_lsb = forAll oneByte $ \bs ->+  let b = head $ BS.unpack bs+  in testBit b 7 === False++prop_oneByte_range :: Property+prop_oneByte_range = forAll oneByte $ \bs ->+  let s = sum $ fmap fromIntegral $ BS.unpack bs+  in (s >= 0 && s <= 127)++prop_twoByte_range :: Property+prop_twoByte_range = forAll twoByte $ \bs ->+  let s = sum $ fmap fromIntegral $ BS.unpack bs+  in (s >= 320 && s <= 65439)++prop_threeByte_range :: Property+prop_threeByte_range = forAll threeByte $ \bs ->+  let s = sum $ fmap fromIntegral $ BS.unpack bs+  in (s >= 480 && s <= 16777071)++prop_validUtf81 :: Property+prop_validUtf81 = forAll utf8BS1 $ \bs ->+  BS.length bs >= 1++return []+props :: IO Bool+props = $quickCheckAll++main :: IO ()+main = props >>= flip when exitFailure . not