packages feed

json-api-lib 0.1.0.0 → 0.1.1.0

raw patch · 5 files changed

+98/−20 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Network.JSONApi: PageNum :: Int -> PageNum
+ Network.JSONApi: PageSize :: Int -> PageSize
+ Network.JSONApi: ResourceCount :: Int -> ResourceCount
+ Network.JSONApi: [getPageNum] :: PageNum -> Int
+ Network.JSONApi: [getPageSize] :: PageSize -> Int
+ Network.JSONApi: [getResourceCount] :: ResourceCount -> Int
+ Network.JSONApi: newtype PageNum
+ Network.JSONApi: newtype PageSize
+ Network.JSONApi: newtype ResourceCount
+ Network.JSONApi.Resource: PageNum :: Int -> PageNum
+ Network.JSONApi.Resource: PageSize :: Int -> PageSize
+ Network.JSONApi.Resource: ResourceCount :: Int -> ResourceCount
+ Network.JSONApi.Resource: [getPageNum] :: PageNum -> Int
+ Network.JSONApi.Resource: [getPageSize] :: PageSize -> Int
+ Network.JSONApi.Resource: [getResourceCount] :: ResourceCount -> Int
+ Network.JSONApi.Resource: instance GHC.Show.Show Network.JSONApi.Resource.PageNum
+ Network.JSONApi.Resource: instance GHC.Show.Show Network.JSONApi.Resource.PageSize
+ Network.JSONApi.Resource: instance GHC.Show.Show Network.JSONApi.Resource.ResourceCount
+ Network.JSONApi.Resource: newtype PageNum
+ Network.JSONApi.Resource: newtype PageSize
+ Network.JSONApi.Resource: newtype ResourceCount
- Network.JSONApi: indexLinks :: ResourcefulEntity e => e -> Maybe Int -> Maybe Int -> Maybe Int -> Links
+ Network.JSONApi: indexLinks :: ResourcefulEntity e => e -> Maybe Text -> PageSize -> PageNum -> ResourceCount -> Links
- Network.JSONApi.Resource: indexLinks :: ResourcefulEntity e => e -> Maybe Int -> Maybe Int -> Maybe Int -> Links
+ Network.JSONApi.Resource: indexLinks :: ResourcefulEntity e => e -> Maybe Text -> PageSize -> PageNum -> ResourceCount -> Links

Files

json-api-lib.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.0  name:                json-api-lib-version:             0.1.0.0+version:             0.1.1.0 homepage:            https://github.com/shirren/json-api-lib bug-reports:         https://github.com/shirren/json-api-lib/issues license:             MIT
src/Network/JSONApi.hs view
@@ -7,8 +7,11 @@ , D.ErrorDocument (..) , D.Included , E.Error (..)+, R.PageNum (..)+, R.PageSize (..) , R.Relationship , R.Resource (..)+, R.ResourceCount (..) , R.Relationships , R.ResourcefulEntity (..) , I.HasIdentifier (..)
src/Network/JSONApi/Document.hs view
@@ -84,10 +84,6 @@ newtype Included = Included [Value]   deriving (Show) --- instance Monoid Included where---   mempty = Included []---   mappend (Included as) (Included bs) = Included (as <> bs)- {- | Constructor function for the Document data type. 
src/Network/JSONApi/Resource.hs view
@@ -4,7 +4,10 @@ Specification: <http://jsonapi.org/format/#document-resource-objects> -} module Network.JSONApi.Resource-( Resource (..)+( PageNum (..)+, PageSize (..)+, Resource (..)+, ResourceCount (..) , Relationships , ResourcefulEntity (..) , Relationship@@ -20,8 +23,8 @@ import qualified Data.Aeson as AE import           Data.Aeson.Types (fieldLabelModifier) import           Data.Map (Map)-import           Data.Maybe (fromMaybe) import qualified Data.Map as Map+import           Data.Maybe (fromMaybe) import           Data.Text (Text, pack)  import           GHC.Generics hiding (Meta)@@ -142,25 +145,41 @@ Helper function to build relative links for a single resource of type ResourceEntity -} showLink :: ResourcefulEntity e => e -> Links-showLink resource = mkLinks [ ("self", selfLink) ]+showLink resource = mkLinks [ ("self", buildLink) ]   where-    selfLink = "/" <> resourceType resource <> "/" <> resourceIdentifier resource+    buildLink = "/" <> resourceType resource <> "/" <> resourceIdentifier resource  {- |+We can specify limits on the number of rows we would like back from the database+-}+newtype PageSize = PageSize {+  getPageSize :: Int+} deriving Show++newtype PageNum = PageNum {+  getPageNum :: Int+} deriving Show++newtype ResourceCount = ResourceCount {+  getResourceCount :: Int+} deriving Show++{- | Helper function to beuild relative links for a collection of resources of type ResourceEntity.  This helper function assumes that the first page is always page 0. -}-indexLinks :: ResourcefulEntity e => e -> Maybe Int -> Maybe Int -> Maybe Int -> Links-indexLinks resource mPageSize mPageNo documentCount = mkLinks [-     ("self", genLink pageNo)+indexLinks :: ResourcefulEntity e => e -> Maybe Text -> PageSize -> PageNum -> ResourceCount -> Links+indexLinks resource baseUrl pageSize pageNum resourceCount = mkLinks [+     ("self", genLink pgNum)     ,("first", genLink (0 :: Int))-    ,("prev", genLink (if pageNo - 1 < 0 then 0 else pageNo - 1))-    ,("next", genLink (pageNo + 1))-    ,("last", genLink ((fromMaybe 0 documentCount `quot` pageSize) - 1 ))]+    ,("prev", genLink (if pgNum - 1 < 0 then 0 else pgNum - 1))+    ,("next", genLink (pgNum + 1))+    ,("last", genLink ((resCount `quot` pgSize) - 1))]   where-    pageSize = fromMaybe 10 mPageSize-    pageNo = fromMaybe 0 mPageNo-    genLink no = "/" <> resourceType resource <> "?" <>+    pgNum = if getPageNum pageNum < 0 then 0 else getPageNum pageNum+    pgSize = if getPageSize pageSize <= 0 then 1 else getPageSize pageSize+    resCount = if getResourceCount resourceCount < 0 then 0 else getResourceCount resourceCount+    genLink no = fromMaybe "" baseUrl <> "/" <> resourceType resource <> "?" <>                 encodeText "page[number]" <> "=" <> (pack . show) no <>-                "&" <> encodeText "page[size]" <> "=" <> (pack . show) pageSize+                "&" <> encodeText "page[size]" <> "=" <> (pack . show) pgSize
test/Network/JSONApi/ResourceSpec.hs view
@@ -16,12 +16,72 @@ main = hspec spec  spec :: Spec-spec =+spec = do   describe "JSON serialization" $     it "can be encoded and decoded from JSON" $ do       let encodedJson = BS.unpack . prettyEncode $ toResource testObject       let decodedJson = AE.decode (BS.pack encodedJson) :: Maybe (Resource TestObject)       isJust decodedJson `shouldBe` True++  describe "Self links" $+    it "can be constructed for a single high level resource" $ do+      let links = showLink testObject+      links `shouldBe` mkLinks [ ("self", "/TestObject/1") ]++  describe "Index links" $ do+    it "should always start at page 0" $ do+      let links = indexLinks testObject Nothing (PageSize 10) (PageNum 1) (ResourceCount 20)+      links `shouldBe` mkLinks [+          ("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")+        , ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")+        , ("next","/TestObject?page%5Bnumber%5D=2&page%5Bsize%5D=10")+        , ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")+        , ("self","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")]++    it "should never have a negative prev page" $ do+      let links = indexLinks testObject Nothing (PageSize 10) (PageNum 0) (ResourceCount 20)+      links `shouldBe` mkLinks [+          ("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")+        , ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")+        , ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")+        , ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")+        , ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")]++    it "should handle a page size of 0" $ do+      let links = indexLinks testObject Nothing (PageSize 0) (PageNum 0) (ResourceCount 2)+      links `shouldBe` mkLinks [+          ("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")+        , ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")+        , ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")+        , ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")+        , ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")]++    it "should handle a negative page num" $ do+      let links = indexLinks testObject Nothing (PageSize 0) (PageNum $ -1) (ResourceCount 2)+      links `shouldBe` mkLinks [+          ("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")+        , ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")+        , ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")+        , ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")+        , ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")]++    it "should handle a negative resource count" $ do+      let links = indexLinks testObject Nothing (PageSize 1) (PageNum 0) (ResourceCount $ -1)+      links `shouldBe` mkLinks [+          ("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")+        , ("last","/TestObject?page%5Bnumber%5D=-1&page%5Bsize%5D=1")+        , ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")+        , ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")+        , ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")]++    it "should handle nested resource paths" $ do+      let links = indexLinks testObject (Just "/ParentObject/1") (PageSize 10) (PageNum 1) (ResourceCount 20)+      links `shouldBe` mkLinks [+          ("first","/ParentObject/1/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")+        , ("last","/ParentObject/1/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")+        , ("next","/ParentObject/1/TestObject?page%5Bnumber%5D=2&page%5Bsize%5D=10")+        , ("prev","/ParentObject/1/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")+        , ("self","/ParentObject/1/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")]  data TestObject = TestObject   { myId :: Int