buffer-builder 0.2.0.2 → 0.2.0.3
raw patch · 4 files changed
+197/−1 lines, 4 filesnew-uploaderPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- buffer-builder.cabal +2/−1
- test/BufferTest.hs +43/−0
- test/JsonTest.hs +122/−0
- test/Utf8Test.hs +30/−0
buffer-builder.cabal view
@@ -1,5 +1,5 @@ name: buffer-builder-version: 0.2.0.2+version: 0.2.0.3 synopsis: Library for efficiently building up buffers, one piece at a time description: @@ -47,6 +47,7 @@ stability: experimental homepage: https://github.com/chadaustin/buffer-builder cabal-version: >=1.10+extra-source-files: test/*.hs library exposed-modules:
+ test/BufferTest.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE MagicHash, OverloadedStrings, TemplateHaskell #-}++module BufferTest (tests, main) where++import qualified Data.ByteString.Char8 as BSC+import Test.Tasty+import Test.Tasty.TH+import Test.Tasty.QuickCheck+import Test.Tasty.HUnit+import Data.BufferBuilder++case_append_bytes :: Assertion+case_append_bytes = do+ let result = runBufferBuilder $ do+ appendChar8 'f'+ appendChar8 'o'+ appendChar8 'o'+ assertEqual "matches" "foo" result++case_append_string :: Assertion+case_append_string = do+ let result = runBufferBuilder $ do+ appendChar8 'f'+ appendChar8 'o'+ appendChar8 'o'+ appendBS "bar"+ assertEqual "matches" "foobar" result++case_append_literals :: Assertion+case_append_literals = do+ let result = runBufferBuilder $ do+ appendLiteral "foo"#+ appendLiteral "bar"#+ assertEqual "matches" "foobar" result++prop_match_intDec :: Int -> Bool+prop_match_intDec i = runBufferBuilder (appendDecimalSignedInt i) == (BSC.pack $ show i)++tests :: TestTree+tests = $(testGroupGenerator)++main :: IO ()+main = defaultMain tests
+ test/JsonTest.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE MagicHash, OverloadedStrings, TemplateHaskell, ExistentialQuantification #-}++module JsonTest where++import Data.Foldable (foldMap)+import Test.Tasty+import Test.Tasty.TH+import qualified Data.Attoparsec.ByteString as Atto+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck+import Data.Monoid ((<>), Monoid (mconcat, mempty))+import Data.String (IsString (..))+import Data.BufferBuilder.Json+import qualified Data.Aeson as Aeson+import qualified Data.Aeson.Parser as JsonParse+import qualified Data.ByteString as BS+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Vector as Vector++ae :: (IsString a, Show a, Eq a) => String -> a -> Assertion+ae expected actual = assertEqual expected (fromString expected) actual++case_encode_int :: IO ()+case_encode_int = do+ ae "-42" (encodeJson (-42::Int))+ ae "9" (encodeJson (9::Int))++case_encode_bool :: IO ()+case_encode_bool = do+ ae "true" (encodeJson True)+ ae "false" (encodeJson False)++case_encode_text :: IO ()+case_encode_text = do+ ae "\"hello\"" (encodeJson ("hello" :: Text))+ ae "\"\"" (encodeJson ("" :: Text))++ ae "\"\\\"\\\\\\n\\r\\t\"" (encodeJson (fromString ['\"', '\\', '\n', '\r', '\t'] :: Text))++case_encode_object :: IO ()+case_encode_object = do+ ae "{\"key\":\"value\"}" (encodeJson ("key" .= ("value" :: Text)))+ ae "{\"key\":\"value\",\"key2\":[5,6,7]}"+ (encodeJson ("key" .= ("value" :: Text) <> "key2" .= ([5,6,7] :: [Int])))+ ae "{}" $ encodeJson $ ((mempty :: ObjectBuilder) <> mempty) <> (mempty <> mempty)+ ae "[]" (encodeJson ([] :: [Int]))++case_monoid_laws :: IO ()+case_monoid_laws = do+ -- TODO QuickCheck+ let a = "key" .= ("value" :: Text)+ b = "key2" .= (999 :: Int)+ c = "key3" .= ([1,2,3] :: [Int])+ assertEqual "Left identity" (encodeJson a) (encodeJson (mempty <> a))+ assertEqual "Right identity" (encodeJson a) (encodeJson (a <> mempty))+ assertEqual "Associativity" (encodeJson (a <> (b <> c))) (encodeJson ((a <> b) <> c))+ assertEqual "mconcat" (encodeJson (mconcat [a, b, c])) (encodeJson (a <> b <> c))++data JsonValue = forall a. ToJson a => JsonValue a++instance ToJson JsonValue where+ toJson (JsonValue a) = toJson a++instance Show JsonValue where+ show jv = show $ encodeJson jv++shrink10x :: Gen a -> Gen a+shrink10x a = sized $ \size ->+ let newSize = max 1 (size `div` 10)+ in resize newSize a++instance Arbitrary JsonValue where+ arbitrary = do+ i <- fmap (`mod` 9) arbitrary :: Gen Int+ case i of+ 0 -> fmap (JsonValue . array)+ (shrink10x arbitrary :: Gen [JsonValue])+ 1 -> fmap (JsonValue . Vector.fromList)+ (shrink10x arbitrary :: Gen [JsonValue])+ 2 -> fmap (JsonValue . Text.pack) (arbitrary :: Gen String)+ 3 -> fmap JsonValue (arbitrary :: Gen Int)+ 4 -> fmap JsonValue (arbitrary :: Gen Double)+ 5 -> return $ JsonValue True+ 6 -> return $ JsonValue False+ 7 -> return $ JsonValue (Nothing :: Maybe Int)+ 8 -> fmap JsonValue (shrink10x arbitrary :: Gen JsonObject)+ _ -> error "Andy made a mistake"++newtype JsonObject = JsonObject [(Text, JsonValue)]++instance Arbitrary JsonObject where+ arbitrary = do+ p1 <- arbitrary+ return $ JsonObject [(Text.pack k, v) | (k, v) <- p1]++instance ToJson JsonObject where+ toJson (JsonObject pairs) =+ toJson $ foldMap makePair pairs+ where+ makePair (k, v) = k .= v++decodeJsonFragment :: Aeson.FromJSON j => BS.ByteString -> Maybe j+decodeJsonFragment str = case parsed of+ Right r -> case Aeson.fromJSON r of+ Aeson.Success a -> Just a+ _ -> Nothing+ _ -> Nothing+ where+ parsed = Atto.parseOnly JsonParse.value' str++prop_always_produces_legal_json :: JsonValue -> Bool+prop_always_produces_legal_json jv =+ case decodeJsonFragment $ encodeJson jv :: Maybe Aeson.Value of+ Just _ -> True+ Nothing -> False++tests :: TestTree+tests = $(testGroupGenerator)++main :: IO ()+main = defaultMain tests
+ test/Utf8Test.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE MagicHash, OverloadedStrings, TemplateHaskell #-}++module Utf8Test (tests, main) where++import Test.Tasty+import Test.Tasty.TH+import Test.Tasty.HUnit+import Data.BufferBuilder.Utf8+import qualified Data.Text as Text+import qualified Data.Text.Encoding as TE++case_append_string :: Assertion+case_append_string = do+ let str = "foo\NUL\1234"+ let bb = runUtf8Builder $ do+ appendString str+ assertEqual "matches" (Text.pack str) $ TE.decodeUtf8 bb++case_append_chars :: Assertion+case_append_chars = do+ let bb = runUtf8Builder $ do+ appendChar '\NUL'+ appendChar '\x1234'+ assertEqual "matches" (TE.encodeUtf8 "\NUL\x1234") bb++tests :: TestTree+tests = $(testGroupGenerator)++main :: IO ()+main = defaultMain tests