{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- orphan Arbitrary instance is fine import qualified Data.Map as Map import Test.Hspec import Test.QuickCheck import Data.BEncode import Data.ByteString.Lazy (pack) instance Arbitrary BEncode where arbitrary = sized bencode' bencode' :: Int -> Gen BEncode bencode' 0 = oneof [BInt `fmap` arbitrary, (BString . pack) `fmap` arbitrary] bencode' n = oneof [ BInt `fmap` arbitrary, (BString . pack) `fmap` arbitrary :: Gen BEncode, BList `fmap` (resize (n `div` 2) arbitrary), (BDict . Map.fromList) `fmap` (resize (n `div` 2) arbitrary) ] main :: IO () main = hspec $ do let bll = BList [BInt (-1), BInt 0, BInt 1, BInt 2, BInt 3, BString "four"] describe "Data.BEncode encoding" $ do it "encodes integers" $ bRead "i42e" `shouldBe` Just (BInt 42) it "encodes strings" $ bRead "3:foo" `shouldBe` Just (BString "foo") it "encodes strings with special characters in Haskell source" $ bRead "5:café" `shouldBe` Just (BString "café") it "encodes lists" $ bRead "l5:helloi42eli-1ei0ei1ei2ei3e4:fouree" `shouldBe` Just (BList [ BString "hello", BInt 42, bll ]) it "encodes nested lists" $ bRead "ll5:helloi62eel3:fooee" `shouldBe` Just (BList [ BList [ BString "hello", BInt 62 ], BList [ BString "foo" ] ]) it "encodes dictionaries" $ bRead "d3:baz3:moo3:foo3:bare" `shouldBe` Just (BDict (Map.fromList [("baz",BString "moo"),("foo",BString "bar")])) it "encodes empty dictionaries" $ bRead "de" `shouldBe` Just (BDict Map.empty) describe "Data.BEncode decoding" $ do -- TODO failing -- it "is the inverse of encoding" $ property $ \bencode -> -- (bRead . bPack) bencode == Just bencode it "decodes int" $ bPack (BInt 42) `shouldBe` "i42e" it "decodes null int" $ bPack (BInt 0) `shouldBe` "i0e" it "decodes negative int" $ bPack (BInt (-42)) `shouldBe` "i-42e" it "decodes string" $ do bPack (BString "foo") `shouldBe` "3:foo" bPack (BString "") `shouldBe` "0:" it "decodes lists" $ bPack (BList [BInt 1, BInt 2, BInt 3]) `shouldBe` "li1ei2ei3ee" it "decodes lists of lists" $ bPack (BList [ BList [BInt 1], BInt 1, BInt 2, BInt 3]) `shouldBe` "lli1eei1ei2ei3ee" it "decodes hash" $ do let d = Map.fromList [("foo", BString "bar"), ("baz",BString "qux")] bPack (BDict d) `shouldBe` "d3:baz3:qux3:foo3:bare" -- FIX -- it "decodes unicode" $ do -- bPack (BString "café") `shouldBe` "5:café" -- bPack (BList [BString "你好", BString "中文"]) `shouldBe` "l6:你好6:中文e" it "decodes lists of lists" $ bRead "l5:helloi42eli-1ei0ei1ei2ei3e4:fouree" `shouldBe` Just (BList [ BString "hello", BInt 42, bll])