{-# LANGUAGE OverloadedStrings #-}
import Test.Hspec
import Control.Monad.Reader (runReader)
import Data.Aeson
import Data.Aeson.Prefix
import Data.ByteString (ByteString)
import Data.Maybe (fromJust)
import Data.Text (Text)
defaultSeparator :: Separator
defaultSeparator = "."
defaultPrefix :: Text
defaultPrefix = "prefix"
optionsDefault :: Options
optionsDefault = Options False defaultSeparator Nothing
optionsPrefixArrays :: Options
optionsPrefixArrays = Options True defaultSeparator Nothing
optionsWithPrefix :: Options
optionsWithPrefix = Options False defaultSeparator (Just defaultPrefix)
optionsWithPrefixAndPrefixArrays :: Options
optionsWithPrefixAndPrefixArrays = Options True defaultSeparator (Just defaultPrefix)
decodeExample :: ByteString -> Value
decodeExample = fromJust . decodeStrict'
prefixTest :: Options -> ByteString -> ByteString -> Expectation
prefixTest opts input expected = (flip runReader opts . prefix) (decodeExample input) `shouldBe` decodeExample expected
allOptions :: [Options]
allOptions = [ optionsDefault
, optionsPrefixArrays
, optionsWithPrefix
, optionsWithPrefixAndPrefixArrays
]
-- Test Inputs
inputSimple :: ByteString
inputSimple = "{ \"a\": 1 }"
inputOneLevel :: ByteString
inputOneLevel = "{ \"a\": { \"b\": 1, \"c\": 2 } }"
inputTwoLevel :: ByteString
inputTwoLevel = "{ \"a\": { \"b\": { \"d\": 1 }, \"c\": { \"e\": 2 } } }"
inputTopArray :: ByteString
inputTopArray = "[ { \"a\": { \"b\": 1 } }, { \"a\": { \"b\": 2 } } ]"
inputWithArrayOneLevel :: ByteString
inputWithArrayOneLevel = "{ \"a\": [ { \"b\": { \"c\": 1 } }, { \"b\": { \"c\": 2 } } ] }"
main :: IO ()
main = hspec $
describe "Data.Aeson.Prefix" $
describe "prefix" $ do
it "doesn't change empty object" $
mapM_ (\o -> prefixTest o "{}" "{}") allOptions
it "doesn't change flat array" $ do
let input = "[\"a\", \"b\"]"
mapM_ (\o -> prefixTest o input input) allOptions
describe "default options" $ do
let shouldResultIn = prefixTest optionsDefault
it "doesn't change simple object" $
inputSimple `shouldResultIn` inputSimple
it "works for one level prefixing" $
inputOneLevel `shouldResultIn` "{ \"a\": { \"a.b\": 1, \"a.c\": 2 } }"
it "works with two level prefixing" $
inputTwoLevel `shouldResultIn` "{ \"a\": { \"a.b\": { \"a.b.d\": 1 }, \"a.c\": { \"a.c.e\": 2 } } }"
it "works with top level array of one level prefixing" $
inputTopArray `shouldResultIn` "[ { \"a\": { \"a.b\": 1 } }, { \"a\": { \"a.b\": 2 } } ]"
it "works with array of one level prefixing" $
inputWithArrayOneLevel `shouldResultIn` "{ \"a\": [ { \"b\": {\"b.c\": 1 } }, { \"b\": { \"b.c\": 2 } } ] }"
describe "options with prefixArrays" $ do
let shouldResultIn = prefixTest optionsPrefixArrays
it "doesn't change simple object" $
inputSimple `shouldResultIn` inputSimple
it "works for one level prefixing" $
inputOneLevel `shouldResultIn` "{ \"a\": { \"a.b\": 1, \"a.c\": 2 } }"
it "works with two level prefixing" $
inputTwoLevel `shouldResultIn` "{ \"a\": { \"a.b\": { \"a.b.d\": 1 }, \"a.c\": { \"a.c.e\": 2 } } }"
it "works with top level array of one level prefixing" $
inputTopArray `shouldResultIn` "[ { \"a\": { \"a.b\": 1 } }, { \"a\": { \"a.b\": 2 } } ]"
it "works with array of one level prefixing" $
inputWithArrayOneLevel `shouldResultIn` "{ \"a\": [ { \"a.b\": {\"a.b.c\": 1 } }, { \"a.b\": { \"a.b.c\": 2 } } ] }"
describe "options with user defined prefix" $ do
let shouldResultIn = prefixTest optionsWithPrefix
it "doesn't change simple object" $
inputSimple `shouldResultIn` "{ \"prefix.a\": 1 }"
it "works for one level prefixing" $
inputOneLevel `shouldResultIn` "{ \"prefix.a\": { \"prefix.a.b\": 1, \"prefix.a.c\": 2 } }"
it "works with two level prefixing" $
inputTwoLevel `shouldResultIn` "{ \"prefix.a\": { \"prefix.a.b\": { \"prefix.a.b.d\": 1 }, \"prefix.a.c\": { \"prefix.a.c.e\": 2 } } }"
it "works with top level array of one level prefixing" $
inputTopArray `shouldResultIn` "[ { \"a\": { \"a.b\": 1 } }, { \"a\": { \"a.b\": 2 } } ]"
it "works with array of one level prefixing" $
inputWithArrayOneLevel `shouldResultIn` "{ \"prefix.a\": [ { \"b\": {\"b.c\": 1 } }, { \"b\": { \"b.c\": 2 } } ] }"
describe "options with prefixArrays and user defined prefix" $ do
let shouldResultIn = prefixTest optionsWithPrefixAndPrefixArrays
it "doesn't change simple object" $
inputSimple `shouldResultIn` "{ \"prefix.a\": 1 }"
it "works for one level prefixing" $
inputOneLevel `shouldResultIn` "{ \"prefix.a\": { \"prefix.a.b\": 1, \"prefix.a.c\": 2 } }"
it "works with two level prefixing" $
inputTwoLevel `shouldResultIn` "{ \"prefix.a\": { \"prefix.a.b\": { \"prefix.a.b.d\": 1 }, \"prefix.a.c\": { \"prefix.a.c.e\": 2 } } }"
it "works with top level array of one level prefixing" $
inputTopArray `shouldResultIn` "[ { \"prefix.a\": { \"prefix.a.b\": 1 } }, { \"prefix.a\": { \"prefix.a.b\": 2 } } ]"
it "works with array of one level prefixing" $
inputWithArrayOneLevel `shouldResultIn` "{ \"prefix.a\": [ { \"prefix.a.b\": {\"prefix.a.b.c\": 1 } }, { \"prefix.a.b\": { \"prefix.a.b.c\": 2 } } ] }"