packages feed

buffer-builder 0.2.4.0 → 0.2.4.1

raw patch · 8 files changed

+103/−104 lines, 8 filesdep +HTFdep −HUnitdep −tastydep −tasty-hunitPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: HTF

Dependencies removed: HUnit, tasty, tasty-hunit, tasty-quickcheck, tasty-th

API changes (from Hackage documentation)

- Data.BufferBuilder: initialCapacity :: Options -> !Int
- Data.BufferBuilder: instance Applicative BufferBuilder
- Data.BufferBuilder: instance Exception BufferOutOfMemoryError
- Data.BufferBuilder: instance Functor BufferBuilder
- Data.BufferBuilder: instance Monad BufferBuilder
- Data.BufferBuilder: instance Show BufferOutOfMemoryError
- Data.BufferBuilder: instance Typeable BufferOutOfMemoryError
- Data.BufferBuilder: trimFinalBuffer :: Options -> !Bool
- Data.BufferBuilder.Json: instance (Prim a, ToJson a) => ToJson (Vector a)
- Data.BufferBuilder.Json: instance (Storable a, ToJson a) => ToJson (Vector a)
- Data.BufferBuilder.Json: instance (ToJsonString k, ToJson v) => ToJson (HashMap k v)
- Data.BufferBuilder.Json: instance (Vector Vector a, ToJson a) => ToJson (Vector a)
- Data.BufferBuilder.Json: instance Monoid ObjectBuilder
- Data.BufferBuilder.Json: instance ToJson Bool
- Data.BufferBuilder.Json: instance ToJson Double
- Data.BufferBuilder.Json: instance ToJson Int
- Data.BufferBuilder.Json: instance ToJson JsonString
- Data.BufferBuilder.Json: instance ToJson ObjectBuilder
- Data.BufferBuilder.Json: instance ToJson Text
- Data.BufferBuilder.Json: instance ToJson Value
- Data.BufferBuilder.Json: instance ToJson a => ToJson (Maybe a)
- Data.BufferBuilder.Json: instance ToJson a => ToJson (Vector a)
- Data.BufferBuilder.Json: instance ToJson a => ToJson [a]
- Data.BufferBuilder.Json: instance ToJsonString JsonString
- Data.BufferBuilder.Json: instance ToJsonString Text
- Data.BufferBuilder.Utf8: instance Applicative Utf8Builder
- Data.BufferBuilder.Utf8: instance Functor Utf8Builder
- Data.BufferBuilder.Utf8: instance Monad Utf8Builder
+ Data.BufferBuilder: [initialCapacity] :: Options -> !Int
+ Data.BufferBuilder: [trimFinalBuffer] :: Options -> !Bool
+ Data.BufferBuilder: instance GHC.Base.Applicative Data.BufferBuilder.BufferBuilder
+ Data.BufferBuilder: instance GHC.Base.Functor Data.BufferBuilder.BufferBuilder
+ Data.BufferBuilder: instance GHC.Base.Monad Data.BufferBuilder.BufferBuilder
+ Data.BufferBuilder: instance GHC.Exception.Exception Data.BufferBuilder.BufferOutOfMemoryError
+ Data.BufferBuilder: instance GHC.Show.Show Data.BufferBuilder.BufferOutOfMemoryError
+ Data.BufferBuilder.Json: instance (Data.BufferBuilder.Json.ToJsonString k, Data.BufferBuilder.Json.ToJson v) => Data.BufferBuilder.Json.ToJson (Data.HashMap.Base.HashMap k v)
+ Data.BufferBuilder.Json: instance (Data.Primitive.Types.Prim a, Data.BufferBuilder.Json.ToJson a) => Data.BufferBuilder.Json.ToJson (Data.Vector.Primitive.Vector a)
+ Data.BufferBuilder.Json: instance (Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector a, Data.BufferBuilder.Json.ToJson a) => Data.BufferBuilder.Json.ToJson (Data.Vector.Unboxed.Base.Vector a)
+ Data.BufferBuilder.Json: instance (Foreign.Storable.Storable a, Data.BufferBuilder.Json.ToJson a) => Data.BufferBuilder.Json.ToJson (Data.Vector.Storable.Vector a)
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson Data.BufferBuilder.Json.JsonString
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson Data.BufferBuilder.Json.ObjectBuilder
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson Data.BufferBuilder.Json.Value
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson Data.Text.Internal.Text
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson GHC.Types.Bool
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson GHC.Types.Double
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson GHC.Types.Int
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson a => Data.BufferBuilder.Json.ToJson (Data.Vector.Vector a)
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson a => Data.BufferBuilder.Json.ToJson (GHC.Base.Maybe a)
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJson a => Data.BufferBuilder.Json.ToJson [a]
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJsonString Data.BufferBuilder.Json.JsonString
+ Data.BufferBuilder.Json: instance Data.BufferBuilder.Json.ToJsonString Data.Text.Internal.Text
+ Data.BufferBuilder.Json: instance GHC.Base.Monoid Data.BufferBuilder.Json.ObjectBuilder
+ Data.BufferBuilder.Utf8: instance GHC.Base.Applicative Data.BufferBuilder.Utf8.Utf8Builder
+ Data.BufferBuilder.Utf8: instance GHC.Base.Functor Data.BufferBuilder.Utf8.Utf8Builder
+ Data.BufferBuilder.Utf8: instance GHC.Base.Monad Data.BufferBuilder.Utf8.Utf8Builder

Files

bench/JsonBench.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE OverloadedStrings, RecordWildCards #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MagicHash, DeriveGeneric #-}  module Main (main) where @@ -10,6 +10,7 @@ import Data.Aeson ((.:)) import Data.Monoid ((<>)) import Data.Text (Text)+import GHC.Generics (Generic) import qualified Data.Aeson as Aeson import qualified Data.BufferBuilder.Json as Json import qualified Data.ByteString as BS@@ -19,11 +20,11 @@ import qualified Data.Vector.Unboxed as UnboxedVector  data EyeColor = Green | Blue | Brown-    deriving (Eq, Show)+    deriving (Eq, Show, Generic) data Gender = Male | Female-    deriving (Eq, Show)+    deriving (Eq, Show, Generic) data Fruit = Apple | Strawberry | Banana-    deriving (Eq, Show)+    deriving (Eq, Show, Generic) data Friend = Friend     { fId :: !Int     , fName :: !Text
buffer-builder.cabal view
@@ -1,5 +1,5 @@ name:                buffer-builder-version:             0.2.4.0+version:             0.2.4.1 synopsis:            Library for efficiently building up buffers, one piece at a time description: @@ -81,13 +81,8 @@   build-depends: base ==4.*                , buffer-builder                , text-               , tasty-               , tasty-hunit-               , tasty-th-               , tasty-quickcheck                , quickcheck-instances-               , HUnit-               , text+               , HTF                , vector                , bytestring                , attoparsec
changelog.md view
@@ -1,3 +1,7 @@+0.2.4.1++* Fix a bug with appendEscapedJsonText and Text buffers with nonzero offsets. (Thanks Joe Lee!)+ 0.2.4.0  * Add the ability to calculate the output length of a BufferBuilder without allocating or writing bytes
src/Data/BufferBuilder.hs view
@@ -352,7 +352,7 @@ appendEscapedJsonText !(Text arr ofs len) =     let byteArray = aBA arr     in withHandle $ \h ->-        bw_append_json_escaped_utf16 h len (Ptr (byteArrayContents# byteArray) `plusPtr` ofs)+        bw_append_json_escaped_utf16 h len (Ptr (byteArrayContents# byteArray) `plusPtr` (2 * ofs)) {-# INLINE appendEscapedJsonText #-}  -- | Append a percent-encoded ByteString.  All characters except for
test/BufferTest.hs view
@@ -1,73 +1,96 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-} {-# LANGUAGE MagicHash, OverloadedStrings, TemplateHaskell, FlexibleInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -module BufferTest (tests, main) where+module BufferTest (htf_thisModulesTests) where +import Test.Framework+ 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 import Test.QuickCheck.Instances () -case_append_bytes :: Assertion-case_append_bytes = do+import qualified Data.Text as T+import qualified Data.Text.Internal as TI++getTextOffset :: T.Text -> Int+getTextOffset (TI.Text _array offset _length) = offset++test_append_bytes :: IO ()+test_append_bytes = do     let result = runBufferBuilder $ do             appendChar8 'f'             appendChar8 'o'             appendChar8 'o'-    assertEqual "matches" "foo" result+    assertEqual "foo" result -case_append_string :: Assertion-case_append_string = do+test_append_string :: IO ()+test_append_string = do     let result = runBufferBuilder $ do             appendChar8 'f'             appendChar8 'o'             appendChar8 'o'             appendBS "bar"-    assertEqual "matches" "foobar" result+    assertEqual "foobar" result -case_append_literals :: Assertion-case_append_literals = do+test_append_json_escaped_text_with_zero_offset :: IO ()+test_append_json_escaped_text_with_zero_offset = do+    let t = "foo"+    assertEqual 0 (getTextOffset t)     let result = runBufferBuilder $ do+            appendEscapedJsonText t+            appendBS "bar"+    assertEqual "\"foo\"bar" result++test_append_json_escaped_text_with_nonzero_offset :: IO ()+test_append_json_escaped_text_with_nonzero_offset = do+    let [_, t] = T.split (== '-') "some_prefix-foo"+    assertNotEqual 0 (getTextOffset t)+    let result = runBufferBuilder $ do+            appendEscapedJsonText t+            appendBS "bar"+    assertEqual "\"foo\"bar" result++test_append_literals :: IO ()+test_append_literals = do+    let result = runBufferBuilder $ do             appendLiteral "foo"#             appendLiteral "bar"#-    assertEqual "matches" "foobar" result+    assertEqual "foobar" result -case_append_url_encoded_safe :: Assertion-case_append_url_encoded_safe = do+test_append_url_encoded_safe :: IO ()+test_append_url_encoded_safe = do     let safe = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"     let result = runBufferBuilder $ do             appendUrlEncoded safe-    assertEqual "matches" safe result+    assertEqual safe result -case_append_url_encoded_unsafe :: Assertion-case_append_url_encoded_unsafe = do+test_append_url_encoded_unsafe :: IO ()+test_append_url_encoded_unsafe = do     let safe = "\0\1 /\\$%"     let result = runBufferBuilder $ do             appendUrlEncoded safe-    assertEqual "matches" "%00%01%20%2f%5c%24%25" result+    assertEqual "%00%01%20%2f%5c%24%25" result -case_query_current_length :: Assertion-case_query_current_length = do+test_query_current_length :: IO ()+test_query_current_length = do     let ((f, s), result) = runBufferBuilder' $ do             appendBS "foo"             first <- currentLength             appendBS "bar"             second <- currentLength             return (first, second)-    assertEqual "first length" 3 f-    assertEqual "second length" 6 s-    assertEqual "result" "foobar" result+    assertEqual 3 f+    assertEqual 6 s+    assertEqual "foobar" result -case_calculate_length :: Assertion-case_calculate_length = do+test_calculate_length :: IO ()+test_calculate_length = do     let first = appendBS "foo"     let second = first >> appendBS "bar" -    assertEqual "first length" 3 $ calculateLength first-    assertEqual "second length" 6 $ calculateLength second+    assertEqual 3 $ calculateLength first+    assertEqual 6 $ calculateLength second  prop_match_intDec :: Int -> Bool prop_match_intDec i = runBufferBuilder (appendDecimalSignedInt i) == (BSC.pack $ show i)@@ -98,9 +121,3 @@ prop_length_calculation_matches_actual_length bb =     let cc = bb >> return () in     BSC.length (runBufferBuilder cc) == calculateLength cc--tests :: TestTree-tests = $(testGroupGenerator)--main :: IO ()-main = defaultMain tests
test/JsonTest.hs view
@@ -1,13 +1,12 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-} {-# LANGUAGE MagicHash, OverloadedStrings, TemplateHaskell, ExistentialQuantification #-} -module JsonTest where+module JsonTest (htf_thisModulesTests) where +import Test.Framework+ 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@@ -19,28 +18,28 @@ 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+ae :: (IsString a, Show a, Eq a) => String -> a -> IO ()+ae expected actual = assertEqual (fromString expected) actual -case_encode_int :: IO ()-case_encode_int = do+test_encode_int :: IO ()+test_encode_int = do     ae "-42" (encodeJson (-42::Int))     ae "9" (encodeJson (9::Int)) -case_encode_bool :: IO ()-case_encode_bool = do+test_encode_bool :: IO ()+test_encode_bool = do     ae "true" (encodeJson True)     ae "false" (encodeJson False) -case_encode_text :: IO ()-case_encode_text = do+test_encode_text :: IO ()+test_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+test_encode_object :: IO ()+test_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])))@@ -64,21 +63,21 @@ instance ToJsonString CustomThing where     toJsonString = unsafeStringUtf8Builder . encodeCustomThing -case_encode_object_with_custom_typeclasses :: IO ()-case_encode_object_with_custom_typeclasses = do+test_encode_object_with_custom_typeclasses :: IO ()+test_encode_object_with_custom_typeclasses = do     ae "{\"key\":\"value\"}" $ encodeJson $ ("key" :: Text) `row` ("value" :: Text)     ae "{\"foo/bar/baz\":\"foo/bar/baz\"}" $ encodeJson $ CustomThing `row` CustomThing -case_monoid_laws :: IO ()-case_monoid_laws = do+test_monoid_laws :: IO ()+test_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))+    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 @@ -137,9 +136,3 @@     case decodeJsonFragment $ encodeJson jv :: Maybe Aeson.Value of         Just _ -> True         Nothing -> False--tests :: TestTree-tests = $(testGroupGenerator)--main :: IO ()-main = defaultMain tests
test/Main.hs view
@@ -1,17 +1,12 @@-{-# LANGUAGE TemplateHaskell, OverloadedStrings, MagicHash #-}+{-# OPTIONS_GHC -F -pgmF htfpp #-} -import Test.Tasty+module Main where -import qualified BufferTest-import qualified Utf8Test-import qualified JsonTest+import Test.Framework -allTests :: TestTree-allTests = testGroup "all tests"-    [ BufferTest.tests-    , Utf8Test.tests-    , JsonTest.tests-    ]+import {-@ HTF_TESTS @-} BufferTest+import {-@ HTF_TESTS @-} Utf8Test+import {-@ HTF_TESTS @-} JsonTest  main :: IO ()-main = defaultMain allTests+main = htfMain htf_importedTests
test/Utf8Test.hs view
@@ -1,30 +1,24 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-} {-# LANGUAGE MagicHash, OverloadedStrings, TemplateHaskell #-} -module Utf8Test (tests, main) where+module Utf8Test (htf_thisModulesTests) where -import Test.Tasty-import Test.Tasty.TH-import Test.Tasty.HUnit+import Test.Framework+ 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+test_append_string :: IO ()+test_append_string = do     let str = "foo\NUL\1234"     let bb = runUtf8Builder $ do             appendString str-    assertEqual "matches" (Text.pack str) $ TE.decodeUtf8 bb+    assertEqual (Text.pack str) $ TE.decodeUtf8 bb -case_append_chars :: Assertion-case_append_chars = do+test_append_chars :: IO ()+test_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+    assertEqual (TE.encodeUtf8 "\NUL\x1234") bb