packages feed

collection-json 1.1.0.0 → 1.1.0.1

raw patch · 13 files changed

+310/−282 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Revision history for collection-json +## 1.1.0.1  -- 2017-11-11++* reduce prop usage by using it correctly+* add shrink methods to Arbitrary instances+* move Internal module to External+* fix git URL+* remove broken travis deployment+ ## 1.1.0.0  -- 2017-11-05  * minimize produced JSON in ToJSON instances
collection-json.cabal view
@@ -1,5 +1,5 @@ name:                collection-json-version:             1.1.0.0+version:             1.1.0.1 synopsis:            Collection+JSON—Hypermedia Type Tools  description:@@ -27,7 +27,7 @@  source-repository head   type:     git-  location: https://github.com/alunduil/collection+json.hs+  location: https://github.com/alunduil/collection-json.hs   branch:   develop  library@@ -43,7 +43,7 @@       Data.CollectionJSON    other-modules:-      Internal.Network.URI.JSON+      External.Network.URI.JSON    build-depends:       aeson       >= 0.8 && < 1.2@@ -71,10 +71,10 @@       Data.CollectionJSON     , Data.CollectionJSON.Arbitrary     , Data.CollectionJSONSpec-    , Internal.Network.URI.Arbitrary-    , Internal.Network.URI.ArbitrarySpec-    , Internal.Network.URI.JSON-    , Internal.Network.URI.JSONSpec+    , External.Network.URI.Arbitrary+    , External.Network.URI.ArbitrarySpec+    , External.Network.URI.JSON+    , External.Network.URI.JSONSpec    build-tool-depends:       hspec-discover:hspec-discover == 2.4.*
src/Data/CollectionJSON.hs view
@@ -20,7 +20,7 @@ import Data.Text (Text) import Network.URI (nullURI, URI) -import Internal.Network.URI.JSON ()+import External.Network.URI.JSON ()  -- * Core Data Types 
+ src/External/Network/URI/JSON.hs view
@@ -0,0 +1,23 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++{-# LANGUAGE OverloadedStrings #-}++{-|+Module      : External.Network.URI.JSON+Description : URI FromJSON and ToJSON Instances+Copyright   : (c) Alex Brandt, 2017+License     : MIT++URI Instances for FromJSON and ToJSON+-}+module External.Network.URI.JSON where++import Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), withText)+import Data.Text (unpack)+import Network.URI (parseURIReference, URI, uriToString)++instance FromJSON URI where+  parseJSON = withText "URI" $ maybe (fail "invalid URI") return . parseURIReference . unpack++instance ToJSON URI where+  toJSON u = toJSON $ uriToString id u ""
− src/Internal/Network/URI/JSON.hs
@@ -1,23 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}--{-# LANGUAGE OverloadedStrings #-}--{-|-Module      : Internal.Network.URI.JSON-Description : URI FromJSON and ToJSON Instances-Copyright   : (c) Alex Brandt, 2017-License     : MIT--URI Instances for FromJSON and ToJSON--}-module Internal.Network.URI.JSON where--import Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), withText)-import Data.Text (unpack)-import Network.URI (parseURIReference, URI, uriToString)--instance FromJSON URI where-  parseJSON = withText "URI" $ maybe (fail "invalid URI") return . parseURIReference . unpack--instance ToJSON URI where-  toJSON u = toJSON $ uriToString id u ""
test/Data/CollectionJSON/Arbitrary.hs view
@@ -1,5 +1,7 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} +{-# LANGUAGE RecordWildCards #-}+ {-| Module      : Data.CollectionJSON.Arbitrary Description : Arbitrary Instances for Data.CollectionJSON@@ -12,11 +14,11 @@  import Control.Applicative ((<$>), (<*>)) import Data.Text (pack)-import Test.QuickCheck (Arbitrary (arbitrary))+import Test.QuickCheck (Arbitrary (arbitrary, shrink)) import Test.QuickCheck.Instances ()  import Data.CollectionJSON-import Internal.Network.URI.Arbitrary ()+import External.Network.URI.Arbitrary ()  instance Arbitrary Collection where   arbitrary = Collection (pack "1.0") <$> arbitrary@@ -26,6 +28,8 @@                                       <*> arbitrary                                       <*> arbitrary +  shrink Collection{..} = [ Collection (pack "1.0") cHref' cLinks' cItems' cQueries' cTemplate' cError' | (cHref', cLinks', cItems', cQueries', cTemplate', cError') <- shrink (cHref, cLinks, cItems, cQueries, cTemplate, cError) ]+ instance Arbitrary Link where   arbitrary = Link <$> arbitrary                    <*> arbitrary@@ -33,11 +37,15 @@                    <*> arbitrary                    <*> arbitrary +  shrink Link{..} = [ Link lHref' lRel' lName' lRender' lPrompt' | (lHref', lRel', lName', lRender', lPrompt') <- shrink (lHref, lRel, lName, lRender, lPrompt) ]+ instance Arbitrary Item where   arbitrary = Item <$> arbitrary                    <*> arbitrary                    <*> arbitrary +  shrink Item{..} = [ Item iHref' iData' iLinks' | (iHref', iData', iLinks') <- shrink (iHref, iData, iLinks) ]+ instance Arbitrary Query where   arbitrary = Query <$> arbitrary                     <*> arbitrary@@ -45,15 +53,23 @@                     <*> arbitrary                     <*> arbitrary +  shrink Query{..} = [ Query qHref' qRel' qName' qPrompt' qData' | (qHref', qRel', qName', qPrompt', qData') <- shrink (qHref, qRel, qName, qPrompt, qData) ]+ instance Arbitrary Template where   arbitrary = Template <$> arbitrary +  shrink Template{..} = [ Template tData' | tData' <- shrink tData ]+ instance Arbitrary Error where   arbitrary = Error <$> arbitrary                     <*> arbitrary                     <*> arbitrary +  shrink Error{..} = [ Error eTitle' eCode' eMessage' | (eTitle', eCode', eMessage') <- shrink (eTitle, eCode, eMessage) ]+ instance Arbitrary Datum where   arbitrary = Datum <$> arbitrary                     <*> arbitrary                     <*> arbitrary++  shrink Datum{..} = [ Datum dName' dValue' dPrompt' | (dName', dValue', dPrompt') <- shrink (dName, dValue, dPrompt) ]
test/Data/CollectionJSONSpec.hs view
@@ -29,11 +29,11 @@ spec =   describe "application/vnd.collection+json" $ modifyMaxSize (const 25) $     do describe "RFC compliance (http://amundsen.com/media-types/collection/format/)" $-         do prop "'Template' decode JSON string: \"{}\"" $ isJust (decode "{}" :: Maybe Template)-            prop "'Collection' decode JSON string: \"{\"collection\":{}}\"" $ isJust (decode "{\"collection\":{}}" :: Maybe Collection) +         do it "'Template' decode JSON string: \"{}\"" $ isJust (decode "{}" :: Maybe Template)+            it "'Collection' decode JSON string: \"{\"collection\":{}}\"" $ isJust (decode "{\"collection\":{}}" :: Maybe Collection)          describe "common parse errors" $-         prop "'Collection' errors on \"{}\"" $ isNothing (decode "{}" :: Maybe Collection)+         it "'Collection' errors on \"{}\"" $ isNothing (decode "{}" :: Maybe Collection)         describe "properties" $          context "fromJust . decode . encode == id" $@@ -47,13 +47,13 @@         describe "JSON Missing Keys" $          do context "decode minimal JSON strings" $-              do prop "Datum"      $ isJust (decode mDatum :: Maybe Datum)-                 prop "Error"      $ isJust (decode mError :: Maybe Error)-                 prop "Template"   $ isJust (decode mTemplate :: Maybe Template)-                 prop "Query"      $ isJust (decode mQuery :: Maybe Query)-                 prop "Item"       $ isJust (decode mItem :: Maybe Item)-                 prop "Link"       $ isJust (decode mLink :: Maybe Link)-                 prop "Collection" $ isJust (decode mCollection :: Maybe Collection)+              do it "Datum"      $ isJust (decode mDatum :: Maybe Datum)+                 it "Error"      $ isJust (decode mError :: Maybe Error)+                 it "Template"   $ isJust (decode mTemplate :: Maybe Template)+                 it "Query"      $ isJust (decode mQuery :: Maybe Query)+                 it "Item"       $ isJust (decode mItem :: Maybe Item)+                 it "Link"       $ isJust (decode mLink :: Maybe Link)+                 it "Collection" $ isJust (decode mCollection :: Maybe Collection)              context "encode minimal data to JSON" $               do it "Datum" $
+ test/External/Network/URI/Arbitrary.hs view
@@ -0,0 +1,191 @@+{-# LANGUAGE RecordWildCards #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++{-|+Module      : External.Network.URI.Arbitrary+Description : Arbitrary Instances for Network.URI+Copyright   : (c) Alex Brandt, 2017+License     : MIT++Arbitrary instances for "Network.URI".+-}+module External.Network.URI.Arbitrary () where++import Control.Applicative ((<$>), (<*>))+import Control.Monad (replicateM)+import Data.List (intercalate)+import Network.URI (URI (..), URIAuth (..))+import Test.QuickCheck (Arbitrary (arbitrary, shrink), choose, elements, Gen, listOf, listOf1, oneof, suchThat)++instance Arbitrary URI where+  arbitrary =+    do uriScheme    <- scheme+       uriAuthority <- arbitrary :: Gen (Maybe URIAuth)+       uriPath      <- path (null uriScheme) $ maybe True emptyAuthority uriAuthority+       uriQuery     <- oneof [query, return ""]+       uriFragment  <- oneof [fragment, return ""]++       return URI {..}+    where emptyAuthority URIAuth{..} = all null [uriUserInfo, uriRegName, uriPort]++  shrink URI{..} = [ URI uriScheme' uriAuthority' uriPath' uriQuery' uriFragment' | (uriScheme', uriAuthority', uriPath', uriQuery', uriFragment') <- shrink (uriScheme, uriAuthority, uriPath, uriQuery, uriFragment) ]++instance Arbitrary URIAuth where+  arbitrary = URIAuth <$> userinfo+                      <*> host `suchThat` (not . null)+                      <*> port++  shrink URIAuth{..} = [ URIAuth uriUserInfo' uriRegName' uriPort' | (uriUserInfo', uriRegName', uriPort') <- shrink (uriUserInfo, uriRegName, uriPort) ]++-- * RFC 3986 Generators+--+--   Some generators are handled by the 'Arbitrary' instances above, and others+--   are folded into symbols that are preceeded or followed by identifying+--   tokens.++scheme :: Gen String+scheme =+  do a <- alpha+     r <- listOf $ oneof [alpha, digit, elements ['+', '-', '.']]+     return $ a : (r ++ ":")++userinfo :: Gen String+userinfo =+  do u <- concat <$> userinfo'+     if null u+        then return ""+        else return $ u ++ "@"+  where userinfo' = listOf $ oneof [ replicateM 1 $ oneof [unreserved, subDelims, return ':']+                                   , percentEncoded+                                   ]++host :: Gen String+host = oneof [ ipLiteral+             , ipv4Address+             , regName+             ]++port :: Gen String+port =+  do p <- listOf digit+     if null p+        then return ""+        else return $ ':':p++ipLiteral :: Gen String+ipLiteral =+  do x <- oneof [ ipv6Address+                --, ipvFuture+                ]+     return $ "[" ++ x ++ "]"++{- TODO Check that "Network.URI" implements this correctly.+ipvFuture :: Gen String+ipvFuture =+  do h <- hexdig+     o <- oneof [ unreserved, subDelims, return ':' ]+     return ['v', h, '.', o]+-}++ipv6Address :: Gen String+ipv6Address = concat <$> oneof [ sequence                        [b 6, ls32]+                               , sequence           [return "::", b 5, ls32]+                               , sequence      [h16, return "::", b 4, ls32]+                               , sequence [b 1, h16, return "::", b 3, ls32]+                               , sequence [b 2, h16, return "::", b 2, ls32]+                               , sequence [b 3, h16, return "::", b 1, ls32]+                               , sequence [b 4, h16, return "::",      ls32]+                               , sequence [b 5, h16, return "::",       h16]+                               , sequence [b 6, h16, return "::"]+                               ]+  where b n = fmap concat $ replicateM n $ fmap (++ ":") h16 :: Gen String++h16 :: Gen String+h16 = replicateM 4 hexdig++ls32 :: Gen String+ls32 = oneof [ intercalate ":" <$> replicateM 2 h16+             , ipv4Address+             ]++ipv4Address :: Gen String+ipv4Address = intercalate "." <$> replicateM 4 decOctet++decOctet :: Gen String+decOctet = (show :: Int -> String) <$> choose (0, 255)++regName :: Gen String+regName = fmap concat $ listOf $ oneof [ replicateM 1 unreserved+                                       , percentEncoded+                                       , replicateM 1 subDelims+                                       ]++path :: Bool -> Bool -> Gen String+path emptyScheme emptyURIAuth = if emptyURIAuth+                                   then oneof [ pathAbsolute+                                              , if emptyScheme then pathNoScheme else pathRootless+                                              , return ""+                                              ]+                                   else pathAbEmpty++pathAbEmpty :: Gen String+pathAbEmpty = concat <$> listOf ((('/':) . concat) <$> listOf pchar)++pathAbsolute :: Gen String+pathAbsolute = ('/':) <$> oneof [return "", pathRootless]++pathNoScheme :: Gen String+pathNoScheme = concat <$> sequence [segment1nc, pathAbEmpty]++pathRootless :: Gen String+pathRootless = concat <$> sequence [ concat <$> listOf1 pchar+                                   , pathAbEmpty+                                   ]++segment1nc :: Gen String+segment1nc = oneof [ replicateM 1 unreserved+                   , percentEncoded+                   , replicateM 1 subDelims+                   , replicateM 1 $ return '@'+                   ] ++pchar :: Gen String+pchar = oneof [ replicateM 1 unreserved+              , percentEncoded+              , replicateM 1 subDelims+              , replicateM 1 $ return ':'+              , replicateM 1 $ return '@'+              ]++query :: Gen String+query = fmap (('?':) . concat) $ listOf $ oneof [ pchar+                                                , return "/"+                                                , return "?"+                                                ]++fragment :: Gen String+fragment = fmap (('#':) . concat) $ listOf $ oneof [ pchar+                                                   , return "/"+                                                   , return "?"+                                                   ]++percentEncoded :: Gen String+percentEncoded = ('%':) <$> replicateM 2 hexdig++unreserved :: Gen Char+unreserved = oneof [ alpha, digit, elements ['-', '.', '_', '~']]++subDelims :: Gen Char+subDelims = elements ['!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=']++-- * RFC 2234 Generators++alpha :: Gen Char+alpha = elements $ ['a'..'z'] ++ ['A'..'Z']++digit :: Gen Char+digit = elements ['0'..'9']++hexdig :: Gen Char+hexdig = oneof [digit, elements ['A'..'F']]
+ test/External/Network/URI/ArbitrarySpec.hs view
@@ -0,0 +1,25 @@+{-|+Module      : External.Network.URI.ArbitrarySpec+Description : Tests for External.Network.URI.Arbitrary+Copyright   : (c) Alex Brandt, 2017+License     : MIT++Tests for "External.Network.URI.Arbitrary".+-}+module External.Network.URI.ArbitrarySpec (main, spec) where++import Network.URI (isURIReference, parseURIReference, uriToString)+import Test.Hspec (describe, hspec, Spec)+import Test.Hspec.QuickCheck (prop)++import External.Network.URI.Arbitrary ()++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "properties" $+    do prop "isURIReference (uriToString id u \"\")" $ \ u -> isURIReference (uriToString id u "")++       prop "Just u == parseURIReference (uriToString id u \"\")" $ \ u -> Just u == parseURIReference (uriToString id u "")
+ test/External/Network/URI/JSONSpec.hs view
@@ -0,0 +1,27 @@+{-|+Module      : External.Network.URI.JSONSpec+Description : Tests for External.Network.URI.JSON+Copyright   : (c) Alex Brandt, 2017+License     : MIT++Tests for "External.Network.URI.JSON".+-}+module External.Network.URI.JSONSpec (main, spec) where++import Data.Aeson (decode, encode)+import Data.Maybe (fromJust)+import Network.URI (URI)+import Test.Hspec (describe, hspec, Spec)+import Test.Hspec.QuickCheck (prop)+import Test.Invariant ((<=>))++import External.Network.URI.Arbitrary ()+import External.Network.URI.JSON ()++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "properties" $+    prop "fromJust . decode . encode == id" (fromJust . decode . encode <=> id :: URI -> Bool)
− test/Internal/Network/URI/Arbitrary.hs
@@ -1,187 +0,0 @@-{-# LANGUAGE RecordWildCards #-}--{-# OPTIONS_GHC -fno-warn-orphans #-}--{-|-Module      : Internal.Network.URI.Arbitrary-Description : Arbitrary Instances for Network.URI-Copyright   : (c) Alex Brandt, 2017-License     : MIT--Arbitrary instances for "Network.URI".--}-module Internal.Network.URI.Arbitrary () where--import Control.Applicative ((<$>), (<*>))-import Control.Monad (replicateM)-import Data.List (intercalate)-import Network.URI (URI (..), URIAuth (..))-import Test.QuickCheck (Arbitrary (arbitrary), choose, elements, Gen, listOf, listOf1, oneof, suchThat)--instance Arbitrary URI where-  arbitrary =-    do uriScheme    <- scheme-       uriAuthority <- arbitrary :: Gen (Maybe URIAuth)-       uriPath      <- path (null uriScheme) $ maybe True emptyAuthority uriAuthority-       uriQuery     <- oneof [query, return ""]-       uriFragment  <- oneof [fragment, return ""]--       return URI {..}-    where emptyAuthority URIAuth{..} = all null [uriUserInfo, uriRegName, uriPort]--instance Arbitrary URIAuth where-  arbitrary = URIAuth <$> userinfo-                      <*> host `suchThat` (not . null)-                      <*> port---- * RFC 3986 Generators------   Some generators are handled by the 'Arbitrary' instances above, and others---   are folded into symbols that are preceeded or followed by identifying---   tokens.--scheme :: Gen String-scheme =-  do a <- alpha-     r <- listOf $ oneof [alpha, digit, elements ['+', '-', '.']]-     return $ a : (r ++ ":")--userinfo :: Gen String-userinfo =-  do u <- concat <$> userinfo'-     if null u-        then return ""-        else return $ u ++ "@"-  where userinfo' = listOf $ oneof [ replicateM 1 $ oneof [unreserved, subDelims, return ':']-                                   , percentEncoded-                                   ]--host :: Gen String-host = oneof [ ipLiteral-             , ipv4Address-             , regName-             ]--port :: Gen String-port =-  do p <- listOf digit-     if null p-        then return ""-        else return $ ':':p--ipLiteral :: Gen String-ipLiteral =-  do x <- oneof [ ipv6Address-                --, ipvFuture-                ]-     return $ "[" ++ x ++ "]"--{- TODO Check that "Network.URI" implements this correctly.-ipvFuture :: Gen String-ipvFuture =-  do h <- hexdig-     o <- oneof [ unreserved, subDelims, return ':' ]-     return ['v', h, '.', o]--}--ipv6Address :: Gen String-ipv6Address = concat <$> oneof [ sequence                        [b 6, ls32]-                               , sequence           [return "::", b 5, ls32]-                               , sequence      [h16, return "::", b 4, ls32]-                               , sequence [b 1, h16, return "::", b 3, ls32]-                               , sequence [b 2, h16, return "::", b 2, ls32]-                               , sequence [b 3, h16, return "::", b 1, ls32]-                               , sequence [b 4, h16, return "::",      ls32]-                               , sequence [b 5, h16, return "::",       h16]-                               , sequence [b 6, h16, return "::"]-                               ]-  where b n = fmap concat $ replicateM n $ fmap (++ ":") h16 :: Gen String--h16 :: Gen String-h16 = replicateM 4 hexdig--ls32 :: Gen String-ls32 = oneof [ intercalate ":" <$> replicateM 2 h16-             , ipv4Address-             ]--ipv4Address :: Gen String-ipv4Address = intercalate "." <$> replicateM 4 decOctet--decOctet :: Gen String-decOctet = (show :: Int -> String) <$> choose (0, 255)--regName :: Gen String-regName = fmap concat $ listOf $ oneof [ replicateM 1 unreserved-                                       , percentEncoded-                                       , replicateM 1 subDelims-                                       ]--path :: Bool -> Bool -> Gen String-path emptyScheme emptyURIAuth = if emptyURIAuth-                                   then oneof [ pathAbsolute-                                              , if emptyScheme then pathNoScheme else pathRootless-                                              , return ""-                                              ]-                                   else pathAbEmpty--pathAbEmpty :: Gen String-pathAbEmpty = concat <$> listOf ((('/':) . concat) <$> listOf pchar)--pathAbsolute :: Gen String-pathAbsolute = ('/':) <$> oneof [return "", pathRootless]--pathNoScheme :: Gen String-pathNoScheme = concat <$> sequence [segment1nc, pathAbEmpty]--pathRootless :: Gen String-pathRootless = concat <$> sequence [ concat <$> listOf1 pchar-                                   , pathAbEmpty-                                   ]--segment1nc :: Gen String-segment1nc = oneof [ replicateM 1 unreserved-                   , percentEncoded-                   , replicateM 1 subDelims-                   , replicateM 1 $ return '@'-                   ] --pchar :: Gen String-pchar = oneof [ replicateM 1 unreserved-              , percentEncoded-              , replicateM 1 subDelims-              , replicateM 1 $ return ':'-              , replicateM 1 $ return '@'-              ]--query :: Gen String-query = fmap (('?':) . concat) $ listOf $ oneof [ pchar-                                                , return "/"-                                                , return "?"-                                                ]--fragment :: Gen String-fragment = fmap (('#':) . concat) $ listOf $ oneof [ pchar-                                                   , return "/"-                                                   , return "?"-                                                   ]--percentEncoded :: Gen String-percentEncoded = ('%':) <$> replicateM 2 hexdig--unreserved :: Gen Char-unreserved = oneof [ alpha, digit, elements ['-', '.', '_', '~']]--subDelims :: Gen Char-subDelims = elements ['!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=']---- * RFC 2234 Generators--alpha :: Gen Char-alpha = elements $ ['a'..'z'] ++ ['A'..'Z']--digit :: Gen Char-digit = elements ['0'..'9']--hexdig :: Gen Char-hexdig = oneof [digit, elements ['A'..'F']]
− test/Internal/Network/URI/ArbitrarySpec.hs
@@ -1,25 +0,0 @@-{-|-Module      : Internal.Network.URI.ArbitrarySpec-Description : Tests for Internal.Network.URI.Arbitrary-Copyright   : (c) Alex Brandt, 2017-License     : MIT--Tests for "Internal.Network.URI.Arbitrary".--}-module Internal.Network.URI.ArbitrarySpec (main, spec) where--import Network.URI (isURIReference, parseURIReference, uriToString)-import Test.Hspec (describe, hspec, Spec)-import Test.Hspec.QuickCheck (prop)--import Internal.Network.URI.Arbitrary ()--main :: IO ()-main = hspec spec--spec :: Spec-spec =-  describe "properties" $-    do prop "isURIReference (uriToString id u \"\")" $ \ u -> isURIReference (uriToString id u "")--       prop "Just u == parseURIReference (uriToString id u \"\")" $ \ u -> Just u == parseURIReference (uriToString id u "")
− test/Internal/Network/URI/JSONSpec.hs
@@ -1,27 +0,0 @@-{-|-Module      : Internal.Network.URI.JSONSpec-Description : Tests for Internal.Network.URI.JSON-Copyright   : (c) Alex Brandt, 2017-License     : MIT--Tests for "Internal.Network.URI.JSON".--}-module Internal.Network.URI.JSONSpec (main, spec) where--import Data.Aeson (decode, encode)-import Data.Maybe (fromJust)-import Network.URI (URI)-import Test.Hspec (describe, hspec, Spec)-import Test.Hspec.QuickCheck (prop)-import Test.Invariant ((<=>))--import Internal.Network.URI.Arbitrary ()-import Internal.Network.URI.JSON ()--main :: IO ()-main = hspec spec--spec :: Spec-spec =-  describe "properties" $-    prop "fromJust . decode . encode == id" (fromJust . decode . encode <=> id :: URI -> Bool)