jsop-0.1.0.0: test/Parse.hs
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications, QuasiQuotes #-}
module Parse where
import Data.Aeson
import Data.Aeson.Lens
import qualified Data.Text as T
import Generics.SOP
import JSOP.Parse
import Protolude hiding (All, optional, (:*:))
import Test.Tasty.Hspec (Spec, describe, it, shouldBe)
import Data.Maybe (fromJust)
import Data.String.Interpolate
jSOP'
:: (All Typeable xs, IsProductType a xs)
=> NP (Parser Text) xs
-> Value
-> Either ParseGIssue a
jSOP' = jSOP $ T.splitOn " / "
decodeU :: Text -> Value
decodeU = fromJust . decode . toS
spec_generic :: Spec
spec_generic = do
describe "generic parsers" do
it "can parse an Int in an object" $ shouldBe
do
jSOP'
do required "a number" _Integral :* Nil
do object ["a number" .= Number 2]
do Right (Identity (2 :: Int))
it "can parse an Int in an nested object" $ shouldBe
do
jSOP'
do required "object / a number" _Integral :* Nil
do
object
[ "object" .= object ["a number" .= Number 2]
]
do Right (Identity (2 :: Int))
it "can parse String and Integer" $ shouldBe
do
jSOP'
do
required "a string" _String
:* required "a number" _Integral
:* Nil
do
object
[ "a number" .= Number 2
, "a string" .= ("ciao" :: Text)
]
do Right ("ciao", 2 :: Int)
it "can parse String and Int down different paths" $ shouldBe
do
jSOP
do T.splitOn " / "
do
required "object 1 / a string" _String
:* required "object 2 / a number" _Integral
:* Nil
do decodeU [i|
{
"object 1":
{ "a string": "ciao"
, "ignore me" : 34
}
, "object 2":
{ "a number": 2
, "object 3": {}
}
}
|]
do Right ("ciao", 2 :: Int)
it "can parse String and Int and Optional Int down different paths" $ shouldBe
do
jSOP
do T.splitOn " / "
do
required "object 1 / a string" _String
:* required "object 2 / a number" _Integral
:* optional "object 4 / a number" 42 _Integral
:* Nil
do decodeU [i|
{
"object 1":
{ "a string": "ciao"
, "ignore me" : 34
}
, "object 2":
{ "a number": 2
, "object 3": {}
}
, "object 4": {
"a plumber" :43
}
}
|]
do Right ("ciao", 2 :: Int, 42 :: Int )