diff options
-rw-r--r-- | bittorrent.cabal | 1 | ||||
-rw-r--r-- | src/Data/Torrent.hs | 15 | ||||
-rw-r--r-- | src/Data/Torrent/Piece.hs | 2 | ||||
-rw-r--r-- | tests/Data/Torrent/ClientSpec.hs | 5 | ||||
-rw-r--r-- | tests/Data/Torrent/MagnetSpec.hs | 3 | ||||
-rw-r--r-- | tests/Data/Torrent/MetainfoSpec.hs | 24 |
6 files changed, 41 insertions, 9 deletions
diff --git a/bittorrent.cabal b/bittorrent.cabal index ff181ff8..00f8da49 100644 --- a/bittorrent.cabal +++ b/bittorrent.cabal | |||
@@ -151,6 +151,7 @@ test-suite spec | |||
151 | , bytestring | 151 | , bytestring |
152 | , directory | 152 | , directory |
153 | , filepath | 153 | , filepath |
154 | , time | ||
154 | 155 | ||
155 | , aeson | 156 | , aeson |
156 | , cereal | 157 | , cereal |
diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs index fc0cb10b..4d6461af 100644 --- a/src/Data/Torrent.hs +++ b/src/Data/Torrent.hs | |||
@@ -26,6 +26,7 @@ | |||
26 | module Data.Torrent | 26 | module Data.Torrent |
27 | ( -- * Info dictionary | 27 | ( -- * Info dictionary |
28 | InfoDict (..) | 28 | InfoDict (..) |
29 | , infoDictionary | ||
29 | 30 | ||
30 | -- ** Lenses | 31 | -- ** Lenses |
31 | , infohash | 32 | , infohash |
@@ -131,6 +132,13 @@ instance Hashable InfoDict where | |||
131 | hash = Hashable.hash . idInfoHash | 132 | hash = Hashable.hash . idInfoHash |
132 | {-# INLINE hash #-} | 133 | {-# INLINE hash #-} |
133 | 134 | ||
135 | -- | Smart constructor: add a info hash to info dictionary. | ||
136 | infoDictionary :: LayoutInfo -> PieceInfo -> Bool -> InfoDict | ||
137 | infoDictionary li pinfo private = InfoDict ih li pinfo private | ||
138 | where | ||
139 | ih = IH.hashlazy $ encode $ InfoDict fake_ih li pinfo private | ||
140 | fake_ih = InfoHash "" | ||
141 | |||
134 | getPrivate :: Get Bool | 142 | getPrivate :: Get Bool |
135 | getPrivate = (Just True ==) <$>? "private" | 143 | getPrivate = (Just True ==) <$>? "private" |
136 | 144 | ||
@@ -155,8 +163,8 @@ instance BEncode InfoDict where | |||
155 | ppPrivacy :: Bool -> Doc | 163 | ppPrivacy :: Bool -> Doc |
156 | ppPrivacy privacy = "Privacy: " <> if privacy then "private" else "public" | 164 | ppPrivacy privacy = "Privacy: " <> if privacy then "private" else "public" |
157 | 165 | ||
158 | ppAdditionalInfo :: InfoDict -> Doc | 166 | --ppAdditionalInfo :: InfoDict -> Doc |
159 | ppAdditionalInfo layout = PP.empty | 167 | --ppAdditionalInfo layout = PP.empty |
160 | 168 | ||
161 | instance Pretty InfoDict where | 169 | instance Pretty InfoDict where |
162 | pretty InfoDict {..} = | 170 | pretty InfoDict {..} = |
@@ -246,6 +254,9 @@ instance BEncode URI where | |||
246 | fromBEncode b = decodingError $ "url <" ++ show b ++ ">" | 254 | fromBEncode b = decodingError $ "url <" ++ show b ++ ">" |
247 | {-# INLINE fromBEncode #-} | 255 | {-# INLINE fromBEncode #-} |
248 | 256 | ||
257 | --pico2uni :: Pico -> Uni | ||
258 | --pico2uni = undefined | ||
259 | |||
249 | -- TODO move to bencoding | 260 | -- TODO move to bencoding |
250 | instance BEncode POSIXTime where | 261 | instance BEncode POSIXTime where |
251 | toBEncode pt = toBEncode (floor pt :: Integer) | 262 | toBEncode pt = toBEncode (floor pt :: Integer) |
diff --git a/src/Data/Torrent/Piece.hs b/src/Data/Torrent/Piece.hs index 6cff53d6..7eb4e3d5 100644 --- a/src/Data/Torrent/Piece.hs +++ b/src/Data/Torrent/Piece.hs | |||
@@ -25,6 +25,7 @@ module Data.Torrent.Piece | |||
25 | , isPiece | 25 | , isPiece |
26 | 26 | ||
27 | -- * Piece control | 27 | -- * Piece control |
28 | , HashArray (..) | ||
28 | , PieceInfo (..) | 29 | , PieceInfo (..) |
29 | , pieceCount | 30 | , pieceCount |
30 | 31 | ||
@@ -138,6 +139,7 @@ isPiece pieceLen blk @ (Block i offset _) = | |||
138 | -- Piece control | 139 | -- Piece control |
139 | -----------------------------------------------------------------------} | 140 | -----------------------------------------------------------------------} |
140 | 141 | ||
142 | -- | A flat array of SHA1 sums of each piece. | ||
141 | newtype HashArray = HashArray { unHashArray :: ByteString } | 143 | newtype HashArray = HashArray { unHashArray :: ByteString } |
142 | deriving (Show, Read, Eq, BEncode) | 144 | deriving (Show, Read, Eq, BEncode) |
143 | 145 | ||
diff --git a/tests/Data/Torrent/ClientSpec.hs b/tests/Data/Torrent/ClientSpec.hs index 0ff74f6f..4bc881c3 100644 --- a/tests/Data/Torrent/ClientSpec.hs +++ b/tests/Data/Torrent/ClientSpec.hs | |||
@@ -27,4 +27,7 @@ spec = do | |||
27 | clientInfo "OP0123xxxxxxxxxxxxxx" `shouldBe` "Opera-123" | 27 | clientInfo "OP0123xxxxxxxxxxxxxx" `shouldBe` "Opera-123" |
28 | 28 | ||
29 | it "decode ML donkey style peer id" $ do | 29 | it "decode ML donkey style peer id" $ do |
30 | clientInfo "-ML2.7.2-xxxxxxxxxxx" `shouldBe` "MLdonkey-0" \ No newline at end of file | 30 | clientInfo "-ML2.7.2-xxxxxxxxxxx" `shouldBe` "MLdonkey-0" |
31 | |||
32 | -- TODO XBT, Bits on Wheels, Queen Bee, BitTyrant, TorrenTopia, | ||
33 | -- BitSpirit, Rufus, G3 Torrent, FlashGet \ No newline at end of file | ||
diff --git a/tests/Data/Torrent/MagnetSpec.hs b/tests/Data/Torrent/MagnetSpec.hs index 5adc6df7..3ecf8705 100644 --- a/tests/Data/Torrent/MagnetSpec.hs +++ b/tests/Data/Torrent/MagnetSpec.hs | |||
@@ -3,6 +3,7 @@ module Data.Torrent.MagnetSpec (spec) where | |||
3 | 3 | ||
4 | import Control.Applicative | 4 | import Control.Applicative |
5 | import Data.Maybe | 5 | import Data.Maybe |
6 | import Data.Monoid | ||
6 | import Test.Hspec | 7 | import Test.Hspec |
7 | import Test.QuickCheck | 8 | import Test.QuickCheck |
8 | import Test.QuickCheck.Instances () | 9 | import Test.QuickCheck.Instances () |
@@ -23,7 +24,7 @@ instance Arbitrary URI where | |||
23 | instance Arbitrary Magnet where | 24 | instance Arbitrary Magnet where |
24 | arbitrary = Magnet <$> arbitrary <*> arbitrary | 25 | arbitrary = Magnet <$> arbitrary <*> arbitrary |
25 | <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary | 26 | <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary |
26 | <*> arbitrary <*> arbitrary <*> pure (error "arbitrary magnet") | 27 | <*> arbitrary <*> arbitrary <*> pure mempty |
27 | 28 | ||
28 | magnetEncoding :: Magnet -> Bool | 29 | magnetEncoding :: Magnet -> Bool |
29 | magnetEncoding m = parseMagnet (renderMagnet m) == Just m | 30 | magnetEncoding m = parseMagnet (renderMagnet m) == Just m |
diff --git a/tests/Data/Torrent/MetainfoSpec.hs b/tests/Data/Torrent/MetainfoSpec.hs index 297b28f1..636bb6b1 100644 --- a/tests/Data/Torrent/MetainfoSpec.hs +++ b/tests/Data/Torrent/MetainfoSpec.hs | |||
@@ -7,11 +7,13 @@ import Data.ByteString as BS | |||
7 | import Data.ByteString.Lazy as BL | 7 | import Data.ByteString.Lazy as BL |
8 | import Data.BEncode | 8 | import Data.BEncode |
9 | import Data.Maybe | 9 | import Data.Maybe |
10 | import Data.Time | ||
10 | import Network.URI | 11 | import Network.URI |
11 | import Test.Hspec | 12 | import Test.Hspec |
12 | import Test.QuickCheck | 13 | import Test.QuickCheck |
13 | import Test.QuickCheck.Instances () | 14 | import Test.QuickCheck.Instances () |
14 | 15 | ||
16 | import Data.Torrent.Piece | ||
15 | import Data.Torrent.Layout | 17 | import Data.Torrent.Layout |
16 | import Data.Torrent | 18 | import Data.Torrent |
17 | 19 | ||
@@ -23,8 +25,8 @@ import Data.Torrent | |||
23 | data T a = T | 25 | data T a = T |
24 | 26 | ||
25 | prop_properBEncode :: Show a => BEncode a => Eq a | 27 | prop_properBEncode :: Show a => BEncode a => Eq a |
26 | => T a -> a -> Bool | 28 | => T a -> a -> IO () |
27 | prop_properBEncode _ expected = actual == Right expected | 29 | prop_properBEncode _ expected = actual `shouldBe` Right expected |
28 | where | 30 | where |
29 | actual = decode $ BL.toStrict $ encode expected | 31 | actual = decode $ BL.toStrict $ encode expected |
30 | 32 | ||
@@ -48,13 +50,25 @@ instance Arbitrary LayoutInfo where | |||
48 | , MultiFile <$> arbitrary <*> arbitrary | 50 | , MultiFile <$> arbitrary <*> arbitrary |
49 | ] | 51 | ] |
50 | 52 | ||
53 | instance Arbitrary HashArray where | ||
54 | arbitrary = HashArray <$> arbitrary | ||
55 | |||
56 | instance Arbitrary PieceInfo where | ||
57 | arbitrary = PieceInfo <$> arbitrary <*> arbitrary | ||
58 | |||
51 | instance Arbitrary InfoDict where | 59 | instance Arbitrary InfoDict where |
52 | arbitrary = undefined | 60 | arbitrary = infoDictionary <$> arbitrary <*> arbitrary <*> arbitrary |
61 | |||
62 | pico :: Gen (Maybe NominalDiffTime) | ||
63 | pico = oneof | ||
64 | [ pure Nothing | ||
65 | , (Just . fromIntegral) <$> (arbitrary :: Gen Int) | ||
66 | ] | ||
53 | 67 | ||
54 | instance Arbitrary Torrent where | 68 | instance Arbitrary Torrent where |
55 | arbitrary = Torrent <$> arbitrary | 69 | arbitrary = Torrent <$> arbitrary |
56 | <*> arbitrary <*> arbitrary <*> arbitrary | 70 | <*> arbitrary <*> arbitrary <*> arbitrary |
57 | <*> arbitrary <*> arbitrary <*> arbitrary | 71 | <*> pico <*> arbitrary <*> arbitrary |
58 | <*> arbitrary <*> pure Nothing <*> arbitrary | 72 | <*> arbitrary <*> pure Nothing <*> arbitrary |
59 | 73 | ||
60 | {----------------------------------------------------------------------- | 74 | {----------------------------------------------------------------------- |