http-media 0.6.2 → 0.6.3
raw patch · 13 files changed
+193/−135 lines, 13 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Network.HTTP.Media.Accept: instance Accept ByteString
- Network.HTTP.Media.RenderHeader: instance RenderHeader ByteString
- Network.HTTP.Media.RenderHeader: instance RenderHeader h => RenderHeader [h]
+ Network.HTTP.Media.Accept: instance Network.HTTP.Media.Accept.Accept Data.ByteString.Internal.ByteString
+ Network.HTTP.Media.RenderHeader: instance Network.HTTP.Media.RenderHeader.RenderHeader Data.ByteString.Internal.ByteString
+ Network.HTTP.Media.RenderHeader: instance Network.HTTP.Media.RenderHeader.RenderHeader h => Network.HTTP.Media.RenderHeader.RenderHeader [h]
Files
- http-media.cabal +2/−2
- src/Network/HTTP/Media.hs +11/−9
- src/Network/HTTP/Media/Language/Internal.hs +5/−3
- src/Network/HTTP/Media/MediaType.hs +4/−1
- src/Network/HTTP/Media/MediaType/Internal.hs +11/−9
- src/Network/HTTP/Media/Utils.hs +6/−2
- test/Network/HTTP/Media/Accept/Tests.hs +10/−3
- test/Network/HTTP/Media/Gen.hs +8/−6
- test/Network/HTTP/Media/Language/Tests.hs +26/−16
- test/Network/HTTP/Media/MediaType/Gen.hs +5/−3
- test/Network/HTTP/Media/MediaType/Tests.hs +66/−26
- test/Network/HTTP/Media/Tests.hs +34/−50
- test/Test.hs +5/−5
http-media.cabal view
@@ -1,5 +1,5 @@ name: http-media-version: 0.6.2+version: 0.6.3 license: MIT license-file: LICENSE author: Timothy Jones@@ -77,7 +77,7 @@ default-language: Haskell2010 - ghc-options: -Wall -Werror+ ghc-options: -Wall hs-source-dirs: src
src/Network/HTTP/Media.hs view
@@ -45,24 +45,26 @@ ) where -------------------------------------------------------------------------------import qualified Data.ByteString.Char8 as BS-------------------------------------------------------------------------------- #if MIN_VERSION_base(4, 8, 0)-import Control.Applicative ((<|>))+import Control.Applicative ((<|>)) #else-import Control.Applicative (pure, (<$>), (<*>), (<|>))+import Control.Applicative (pure, (<$>), (<*>), (<|>)) #endif-import Control.Monad (guard, (>=>))-import Data.ByteString (ByteString)-import Data.Maybe (fromMaybe) ------------------------------------------------------------------------------+import qualified Data.ByteString.Char8 as BS++------------------------------------------------------------------------------+import Control.Monad (guard, (>=>))+import Data.ByteString (ByteString)+import Data.Maybe (fromMaybe)++------------------------------------------------------------------------------ import Network.HTTP.Media.Accept as Accept-import Network.HTTP.Media.RenderHeader import Network.HTTP.Media.Language as Language import Network.HTTP.Media.MediaType as MediaType import Network.HTTP.Media.Quality+import Network.HTTP.Media.RenderHeader import Network.HTTP.Media.Utils (trimBS)
src/Network/HTTP/Media/Language/Internal.hs view
@@ -8,6 +8,11 @@ ) where ------------------------------------------------------------------------------+#if !MIN_VERSION_base(4, 8, 0)+import Data.Functor ((<$>))+#endif++------------------------------------------------------------------------------ import qualified Data.ByteString.Char8 as BS import qualified Data.CaseInsensitive as CI @@ -16,9 +21,6 @@ import Data.ByteString (ByteString) import Data.CaseInsensitive (CI, original) import Data.Char (isAlpha)-#if !MIN_VERSION_base(4, 8, 0)-import Data.Functor ((<$>))-#endif import Data.List (isPrefixOf) import Data.Maybe (fromMaybe) import Data.String (IsString (..))
src/Network/HTTP/Media/MediaType.hs view
@@ -58,7 +58,10 @@ -- | Builds a 'MediaType' without parameters. Can produce an error if -- either type is invalid. (//) :: ByteString -> ByteString -> MediaType-a // b = MediaType (ensureR a) (ensureR b) empty+a // b+ | a == "*" && b == "*" = MediaType (CI.mk a) (CI.mk b) empty+ | b == "*" = MediaType (ensureR a) (CI.mk b) empty+ | otherwise = MediaType (ensureR a) (ensureR b) empty ------------------------------------------------------------------------------
src/Network/HTTP/Media/MediaType/Internal.hs view
@@ -11,13 +11,13 @@ import qualified Data.Map as Map -------------------------------------------------------------------------------import Control.Monad (guard)+import Control.Monad (foldM, guard) import Data.ByteString (ByteString) import Data.CaseInsensitive (CI, original)-import Data.String (IsString (..)) import Data.Map (Map) import Data.Maybe (fromMaybe) import Data.Monoid ((<>))+import Data.String (IsString (..)) ------------------------------------------------------------------------------ import Network.HTTP.Media.Accept (Accept (..))@@ -42,15 +42,17 @@ instance Accept MediaType where parseAccept bs = do- let pieces = map trimBS $ BS.split ';' bs- guard $ not (null pieces)- let (m : ps) = pieces- (a, b) = both CI.mk (breakChar '/' m)- guard $ BS.elem '/' m && (a /= "*" || b == "*")- return $ MediaType a b (foldr insert Map.empty ps)+ (s, ps) <- uncons (map trimBS (BS.split ';' bs))+ (a, b) <- breakChar '/' s+ guard $ not (BS.null a || BS.null b) && (a /= "*" || b == "*")+ ps' <- foldM insert Map.empty ps+ return $ MediaType (CI.mk a) (CI.mk b) ps' where+ uncons [] = Nothing+ uncons (a : b) = Just (a, b) both f (a, b) = (f a, f b)- insert = uncurry Map.insert . both CI.mk . breakChar '='+ insert ps =+ fmap (flip (uncurry Map.insert) ps . both CI.mk) . breakChar '=' matches a b | mainType b == "*" = params
src/Network/HTTP/Media/Utils.hs view
@@ -18,8 +18,12 @@ ------------------------------------------------------------------------------ -- | Equivalent to 'Data.ByteString.break' (on equality against the given -- character), but leaves out the byte that the string is broken on.-breakChar :: Char -> ByteString -> (ByteString, ByteString)-breakChar c = fmap BS.tail . BS.break (== c)+breakChar :: Char -> ByteString -> Maybe (ByteString, ByteString)+breakChar c = safeTail . BS.break (== c)+ where+ safeTail (a, b)+ | BS.null b = Nothing+ | otherwise = Just (a, BS.tail b) ------------------------------------------------------------------------------
test/Network/HTTP/Media/Accept/Tests.hs view
@@ -1,10 +1,17 @@+{-# LANGUAGE CPP #-}+ ------------------------------------------------------------------------------ module Network.HTTP.Media.Accept.Tests (tests) where -------------------------------------------------------------------------------import Control.Monad (join, liftM, liftM2)+#if !MIN_VERSION_base(4, 8, 0)+import Control.Applicative ((<$>), (<*>))+#endif++------------------------------------------------------------------------------ import Test.Framework (Test, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck ((===)) ------------------------------------------------------------------------------ import Network.HTTP.Media.Accept@@ -38,11 +45,11 @@ -- required for the 'moreSpecificThan' test. testMoreSpecificThan :: Test testMoreSpecificThan = testProperty "moreSpecificThan" $- join (liftM2 ((not .) . moreSpecificThan)) genByteString+ (not .) . moreSpecificThan <$> genByteString <*> genByteString ------------------------------------------------------------------------------ testMostSpecific :: Test testMostSpecific = testProperty "mostSpecific" $ do string <- genByteString- liftM ((== string) . mostSpecific string) genByteString+ (=== string) . mostSpecific string <$> genByteString
test/Network/HTTP/Media/Gen.hs view
@@ -15,14 +15,16 @@ ) where ------------------------------------------------------------------------------+#if !MIN_VERSION_base(4, 8, 0)+import Data.Functor ((<$>))+#endif++------------------------------------------------------------------------------ import qualified Data.ByteString.Char8 as BS import qualified Data.CaseInsensitive as CI -------------------------------------------------------------------------------#if !MIN_VERSION_base(4, 8, 0)-import Control.Applicative ((<$>))-#endif-import Control.Monad (liftM2, join)+import Control.Monad (join, liftM2) import Data.ByteString (ByteString) import Data.CaseInsensitive (CI, original) import Data.Monoid ((<>))@@ -31,12 +33,12 @@ ------------------------------------------------------------------------------ -- | Produces a non-empty ByteString of random characters from the given set.-genByteStringFrom :: [Char] -> Gen ByteString+genByteStringFrom :: String -> Gen ByteString genByteStringFrom = fmap BS.pack . listOf1 . elements -------------------------------------------------------------------------------genCIByteStringFrom :: [Char] -> Gen (CI ByteString)+genCIByteStringFrom :: String -> Gen (CI ByteString) genCIByteStringFrom = fmap CI.mk . genByteStringFrom
test/Network/HTTP/Media/Language/Tests.hs view
@@ -4,21 +4,26 @@ module Network.HTTP.Media.Language.Tests (tests) where ------------------------------------------------------------------------------+#if !MIN_VERSION_base(4, 8, 0)+import Data.Functor ((<$>))+#endif++------------------------------------------------------------------------------ import qualified Data.ByteString.Char8 as BS -------------------------------------------------------------------------------#if !MIN_VERSION_base(4, 8, 0)-import Control.Applicative ((<$>))-#endif import Control.Monad (join)+import Data.Monoid ((<>)) import Data.String (fromString) import Test.Framework (Test, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck ((.&&.), (===)) ------------------------------------------------------------------------------ import Network.HTTP.Media.Accept-import Network.HTTP.Media.RenderHeader+import Network.HTTP.Media.Language import Network.HTTP.Media.Language.Gen+import Network.HTTP.Media.RenderHeader ------------------------------------------------------------------------------@@ -40,7 +45,7 @@ testEq = testGroup "Eq" [ testProperty "==" $ do lang <- genLanguage- return $ lang == lang+ return $ lang === lang , testProperty "/=" $ do lang <- genLanguage lang' <- genDiffLanguage lang@@ -52,14 +57,14 @@ testShow :: Test testShow = testProperty "show" $ do lang <- genLanguage- return $ parseAccept (BS.pack $ show lang) == Just lang+ return $ parseAccept (BS.pack $ show lang) === Just lang ------------------------------------------------------------------------------ testFromString :: Test testFromString = testProperty "fromString" $ do lang <- genLanguage- return $ lang == fromString (show lang)+ return $ lang === fromString (show lang) ------------------------------------------------------------------------------@@ -99,21 +104,26 @@ testMostSpecific = testGroup "mostSpecific" [ testProperty "With *" $ do lang <- genLanguage- return $ mostSpecific lang anything == lang &&- mostSpecific anything lang == lang+ return $ mostSpecific lang anything === lang .&&.+ mostSpecific anything lang === lang , testProperty "Proper prefix" $ do (pre, lang) <- genMatchingLanguages- return $ mostSpecific lang pre == lang &&- mostSpecific pre lang == lang+ return $ mostSpecific lang pre === lang .&&.+ mostSpecific pre lang === lang , testProperty "Left biased" $ do (lang, lang') <- genNonMatchingLanguages- return $ mostSpecific lang lang' == lang &&- mostSpecific lang' lang == lang'+ return $ mostSpecific lang lang' === lang .&&.+ mostSpecific lang' lang === lang' ] ------------------------------------------------------------------------------ testParseAccept :: Test-testParseAccept = testProperty "parseAccept" $ do- lang <- genLanguage- return $ parseAccept (renderHeader lang) == Just lang+testParseAccept = testGroup "parseAccept"+ [ testProperty "Valid parse"$ do+ lang <- genLanguage+ return $ parseAccept (renderHeader lang) === Just lang+ , testProperty "Trailing hyphen" $ do+ bs <- renderHeader <$> genLanguage+ return $ (parseAccept $ bs <> "-" :: Maybe Language) === Nothing+ ]
test/Network/HTTP/Media/MediaType/Gen.hs view
@@ -29,12 +29,14 @@ ) where ------------------------------------------------------------------------------+#if !MIN_VERSION_base(4, 8, 0)+import Data.Functor ((<$>))+#endif++------------------------------------------------------------------------------ import qualified Data.Map as Map -------------------------------------------------------------------------------#if !MIN_VERSION_base(4, 8, 0)-import Control.Applicative ((<$>))-#endif import Control.Monad (liftM, liftM2) import Data.ByteString (ByteString) import Data.CaseInsensitive (CI, original)
test/Network/HTTP/Media/MediaType/Tests.hs view
@@ -1,25 +1,35 @@+{-# LANGUAGE CPP #-}+ ------------------------------------------------------------------------------ module Network.HTTP.Media.MediaType.Tests (tests) where ------------------------------------------------------------------------------+#if !MIN_VERSION_base(4, 8, 0)+import Data.Functor ((<$>))+#endif++------------------------------------------------------------------------------ import qualified Data.ByteString.Char8 as BS import qualified Data.Map as Map ------------------------------------------------------------------------------ import Control.Monad (join, liftM)+import Data.ByteString (ByteString) import Data.CaseInsensitive (foldedCase)-import Data.String (fromString)-import Data.Maybe (isNothing) import Data.Monoid ((<>))+import Data.String (fromString) import Test.Framework (Test, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck (property, (.&&.), (===))+import Test.QuickCheck.Gen (Gen) ------------------------------------------------------------------------------ import Network.HTTP.Media.Accept import Network.HTTP.Media.Gen-import Network.HTTP.Media.MediaType ((/?), (/.))-import Network.HTTP.Media.MediaType.Internal+import Network.HTTP.Media.MediaType ((/.), (/?)) import Network.HTTP.Media.MediaType.Gen+import Network.HTTP.Media.MediaType.Internal+import Network.HTTP.Media.RenderHeader (renderHeader) ------------------------------------------------------------------------------@@ -43,7 +53,7 @@ testEq = testGroup "Eq" [ testProperty "==" $ do media <- genMediaType- return $ media == media+ return $ media === media , testProperty "/=" $ do media <- genMediaType media' <- genDiffMediaType media@@ -55,14 +65,14 @@ testShow :: Test testShow = testProperty "show" $ do media <- genMediaType- return $ parseAccept (BS.pack $ show media) == Just media+ return $ parseAccept (BS.pack $ show media) === Just media ------------------------------------------------------------------------------ testFromString :: Test testFromString = testProperty "fromString" $ do media <- genMediaType- return $ media == fromString (show media)+ return $ media === fromString (show media) ------------------------------------------------------------------------------@@ -83,12 +93,12 @@ testGet = testGroup "(/.)" [ testProperty "Retrieves property it has" $ do media <- genWithParams- let is n v = (&& media /. foldedCase n == Just v)- return $ Map.foldrWithKey is True $ parameters media+ let is n v = (.&&. media /. foldedCase n === Just v)+ return $ Map.foldrWithKey is (property True) $ parameters media , testProperty "Nothing for property it doesn't have" $ do media <- genWithParams- let is n _ = (&& isNothing (stripParams media /. foldedCase n))- return $ Map.foldrWithKey is True $ parameters media+ let is n _ = (.&&. stripParams media /. foldedCase n === Nothing)+ return $ Map.foldrWithKey is (property True) $ parameters media ] @@ -161,42 +171,72 @@ testMostSpecific = testGroup "mostSpecific" [ testProperty "With */*" $ do media <- genConcreteMediaType- return $ mostSpecific media anything == media &&- mostSpecific anything media == media+ return $ mostSpecific media anything === media .&&.+ mostSpecific anything media === media , testProperty "With type/*" $ do media <- genConcreteMediaType let m1 = media { parameters = Map.empty } m2 = m1 { subType = "*" }- return $ mostSpecific m1 m2 == m1 && mostSpecific m2 m1 == m1+ return $ mostSpecific m1 m2 === m1 .&&. mostSpecific m2 m1 === m1 , testProperty "With parameters" $ do media <- genMediaType params <- genParameters let media' = media { parameters = params } media'' = media { parameters = Map.empty }- return $ mostSpecific media' media'' == media' &&- mostSpecific media'' media' == media'+ return $ mostSpecific media' media'' === media' .&&.+ mostSpecific media'' media' === media' , testProperty "Different types" $ do media <- genConcreteMediaType media' <- genDiffMediaTypeWith genConcreteMediaType media- return $ mostSpecific media media' == media+ return $ mostSpecific media media' === media , testProperty "Left biased" $ do media <- genConcreteMediaType media' <- genConcreteMediaType let media'' = media' { parameters = parameters media }- return $ mostSpecific media media'' == media &&- mostSpecific media'' media == media''+ return $ mostSpecific media media'' === media .&&.+ mostSpecific media'' media === media'' ] ------------------------------------------------------------------------------ testParseAccept :: Test-testParseAccept = testProperty "parseAccept" $ do- media <- genMediaType- let main = mainType media- sub = subType media- params <- renderParameters (parameters media)- let parsed = parseAccept $ foldedCase (main <> "/" <> sub) <> params- return $ parsed == Just media+testParseAccept = testGroup "parseAccept"+ [ testProperty "Valid parse" $ do+ media <- genMediaType+ let main = mainType media+ sub = subType media+ params <- renderParameters (parameters media)+ let parsed = parseAccept $ foldedCase (main <> "/" <> sub) <> params+ return $ parsed === Just media+ , testProperty "No sub" $ do+ bs <- genByteString+ return $ (parseAccept bs :: Maybe MediaType) === Nothing+ , testProperty "Empty main" $ do+ sep <- padString "/"+ bs <- (sep <>) <$> genByteString+ return $ (parseAccept bs :: Maybe MediaType) === Nothing+ , testProperty "Empty sub" $ do+ sep <- padString "/"+ bs <- (<> sep) <$> genByteString+ return $ (parseAccept bs :: Maybe MediaType) === Nothing+ , testProperty "Empty parameters" $ do+ sep <- padString ";"+ bs <- renderHeader <$> genWithoutParams+ return $ (parseAccept (bs <> sep) :: Maybe MediaType) === Nothing+ , testProperty "No value" $+ (=== Nothing) <$> genMediaNameAndParams ""+ , testProperty "Empty value" $ do+ eq <- padString "="+ (=== Nothing) <$> genMediaNameAndParams eq+ ]++genMediaNameAndParams :: ByteString -> Gen (Maybe MediaType)+genMediaNameAndParams eq = do+ sep <- padString ";"+ bs <- renderHeader <$> genByteString+ name <- genByteString+ ps <- genMaybeParameters >>= renderParameters+ return $ parseAccept (bs <> sep <> name <> eq <> sep <> ps) ------------------------------------------------------------------------------
test/Network/HTTP/Media/Tests.hs view
@@ -5,13 +5,13 @@ ------------------------------------------------------------------------------ #if !MIN_VERSION_base(4, 8, 0)-import Control.Applicative ((<$>), (<*>))+import Control.Applicative ((<$>), (<*>)) #endif-import Control.Monad ((>=>), replicateM)-import Data.ByteString (ByteString)++------------------------------------------------------------------------------+import Control.Monad (join, replicateM, (>=>)) import Data.Foldable (foldlM) import Data.Map (empty)-import Data.Maybe (isNothing, listToMaybe) import Data.Monoid ((<>)) import Data.Word (Word16) import Test.Framework (Test, testGroup)@@ -44,15 +44,15 @@ [ testProperty "Without quality" $ do media <- medias rendered <- padConcat (return . renderHeader) media- return $ parseQuality rendered == Just (map maxQuality media)+ return $ parseQuality rendered === Just (map maxQuality media) , testProperty "With quality" $ do media <- qualities rendered <- padConcat padQuality media- return $ parseQuality rendered == Just media+ return $ parseQuality rendered === Just media , testProperty "With extensions" $ do media <- qualities rendered <- padConcat (padQuality >=> padExtensions) media- return $ parseQuality rendered == Just media+ return $ parseQuality rendered === Just media ] where medias = listOf1 genMediaType@@ -81,32 +81,21 @@ ------------------------------------------------------------------------------ testMatchContent :: Test testMatchContent = testGroup "matchContent"- [ testProperty "Most specific" $ do- media <- genConcreteMediaType- let client = renderHeader- [ MediaType "*" "*" empty- , media { subType = "*" }- , media { parameters = empty }- , media- ]- return $ matchAccept [media] client == Just media+ [ testProperty "Matches" $ do+ media <- genMediaType+ return $ matchContent [media] (renderHeader media) === Just media , testProperty "Nothing" $ do- (server, client) <- genServerAndClient- let client' = filter (not . flip any server . matches) client- return . isNothing $ matchAccept server (renderHeader client')- , testProperty "Left biased" $ do- server <- genServer- return $- matchAccept server (renderHeader server) == Just (head server)+ content <- genMediaType+ parsers <- filter (not . matches content) <$> genServer+ return $ matchContent parsers (renderHeader content) === Nothing , testProperty "Against */*" $ do- server <- genServer- let stars = "*/*" :: ByteString+ media <- genMediaType return $- matchAccept server (renderHeader [stars]) == Just (head server)+ matchContent [anything] (renderHeader media) === Just anything , testProperty "Against type/*" $ do- server <- genServer- let client = renderHeader [subStarOf $ head server]- return $ matchAccept server client == Just (head server)+ media <- genMediaType+ let sub = subStarOf media+ return $ matchContent [sub] (renderHeader media) === Just sub ] @@ -114,14 +103,12 @@ testMapContent :: Test testMapContent = testGroup "mapContent" [ testProperty "Matches" $ do- server <- genServer- let zipped = zip server server- return $ mapAccept zipped (renderHeader server) == listToMaybe server+ media <- genMediaType+ return $ mapContent [(media, ())] (renderHeader media) === Just () , testProperty "Nothing" $ do- server <- genServer- client <- listOf1 $ genDiffMediaTypesWith genConcreteMediaType server- let zipped = zip server $ repeat ()- return . isNothing $ mapAccept zipped (renderHeader client)+ content <- genMediaType+ parsers <- join zip . filter (not . matches content) <$> genServer+ return $ mapContent parsers (renderHeader content) === Nothing ] @@ -147,7 +134,7 @@ qs <- replicateM (length server) $ choose (1, 1000) let client = zipWith Quality server qs qmax v q = if qualityValue q > qualityValue v then q else v- return $ match server (qToI client) ==+ return $ match server (qToI client) === Just (qualityData $ foldr1 qmax client) , testProperty "Most specific" $ do media <- genConcreteMediaType@@ -157,30 +144,27 @@ , media { parameters = empty } , media ]- return $ match [media] client == Just media+ return $ match [media] client === Just media , testProperty "Nothing" $ do- server <- genServer- client <- listOf1 $ genDiffMediaTypesWith genConcreteMediaType server- let client' = filter (not . flip any server . matches) client- return . isNothing $ match server- (qToI $ map maxQuality client')+ client <- listOf1 genConcreteMediaType+ server <- filter (not . flip any client . matches) <$> genServer+ return $ match server (qToI $ map maxQuality client) === Nothing , testProperty "Never chooses q=0" $ do server <- genServer- return . isNothing $- match server (qToI $ map minQuality server)+ return $ match server (qToI $ map minQuality server) === Nothing , testProperty "Left biased" $ do server <- genServer let client = qToI $ map maxQuality server- return $ match server client == Just (head server)+ return $ match server client === Just (head server) , testProperty "Against */*" $ do server <- genServer let stars = "*/*" :: MediaType- return $ match server (qToI [maxQuality stars]) ==+ return $ match server (qToI [maxQuality stars]) === Just (head server) , testProperty "Against type/*" $ do server <- genServer let client = qToI [maxQuality (subStarOf $ head server)]- return $ match server client == Just (head server)+ return $ match server client === Just (head server) ] @@ -197,12 +181,12 @@ let client = zipWith Quality server qs qmax q v = if qualityValue q >= qualityValue v then q else v zipped = zip server server- return $ mapf zipped (qToI client) ==+ return $ mapf zipped (qToI client) === Just (qualityData $ foldr1 qmax client) , testProperty "Nothing" $ do (server, client) <- genServerAndClient let zipped = zip server $ repeat "*/*"- return . isNothing $ mapf zipped (qToI $ map maxQuality client)+ return $ mapf zipped (qToI $ map maxQuality client) === Nothing ]
test/Test.hs view
@@ -5,17 +5,17 @@ import Test.Framework (defaultMain, testGroup) -------------------------------------------------------------------------------import qualified Network.HTTP.Media.Tests as Media import qualified Network.HTTP.Media.Accept.Tests as Accept-import qualified Network.HTTP.Media.MediaType.Tests as MediaType import qualified Network.HTTP.Media.Language.Tests as Language+import qualified Network.HTTP.Media.MediaType.Tests as MediaType+import qualified Network.HTTP.Media.Tests as Media ------------------------------------------------------------------------------ main :: IO () main = defaultMain- [ testGroup "MediaType" MediaType.tests- , testGroup "Accept" Accept.tests- , testGroup "Media" Media.tests+ [ testGroup "Accept" Accept.tests , testGroup "Language" Language.tests+ , testGroup "MediaType" MediaType.tests+ , testGroup "Media" Media.tests ]