unleash-client-haskell-core-0.12.0: test/UnleashClientSpecificationRoundtripSpec.hs
-- Copyright © FINN.no AS, Inc. All rights reserved.
module UnleashClientSpecificationRoundtripSpec (
spec,
) where
import Data.Aeson (ToJSON (toJSON), eitherDecodeFileStrict, eitherDecodeStrict)
import qualified Data.Aeson as Aeson
import Data.Aeson.Encode.Pretty (encodePretty)
import Data.Aeson.KeyMap (mapMaybe)
import qualified Data.Aeson.Parser as Parser
import Data.Attoparsec.ByteString (parseOnly)
import qualified Data.ByteString as BS (readFile)
import qualified Data.ByteString.Lazy as BSL
import Data.Foldable (traverse_)
import Test.Hspec
import UnleashSpecificationJsonTypes (Specification)
spec :: Spec
spec =
describe "Parse JSON specification" do
it "parse all specification files and check if input JSON is the same as serialized JSON" do
Right allFiles <- eitherDecodeFileStrict @([FilePath]) "./client-specification/specifications/index.json"
-- Test 13 contains null as a value that is deleted by WithoutNothing
let exclusions = ["13-constraint-operators.json", "16-strategy-variants.json", "17-dependent-features.json"]
let files = filter (not . \path -> any ((==) path) exclusions) allFiles
let paths = ("./client-specification/specifications/" <>) <$> files
traverse_ roundtrip paths
roundtrip :: FilePath -> Expectation
roundtrip filePath = do
putStrLn (" " <> filePath)
bs <- BS.readFile filePath
let eJsonValue = parseOnly Parser.value bs
case eJsonValue of
Right _ -> pure ()
Left e -> print e
let Right jsonValue = eJsonValue
let prettyJson = encodePretty jsonValue
let eSpecification = eitherDecodeStrict @Specification bs
case eSpecification of
Right _ -> pure ()
Left e -> print e
let Right specification = eSpecification
BSL.writeFile "actual.json" $ encodePretty specification
BSL.writeFile "expected.json" prettyJson
encodePretty (WithoutNothing specification) `shouldBe` prettyJson
removeUndefinedProps :: Aeson.Value -> Aeson.Value
removeUndefinedProps v =
case v of
Aeson.Array v' -> Aeson.Array $ removeUndefinedProps <$> v'
Aeson.Object km ->
Aeson.Object $
mapMaybe
( \v' -> case v' of
Aeson.Null -> Nothing
_ -> Just $ removeUndefinedProps v'
)
km
_ -> v
newtype WithoutNothing a = WithoutNothing a
instance (ToJSON a) => ToJSON (WithoutNothing a) where
toJSON (WithoutNothing a) = removeUndefinedProps $ toJSON a