{-# LANGUAGE TypeApplications #-} module Main where import Test.Hspec import Versioning.Base import Versioning.JSON import Versioning.Upgrade import Tests.Versioning.Fixtures (Foo (..), SumType (..), foo0, foo2, fooJsonV0, fooJsonV2, sumType) main :: IO () main = hspec $ do describe "Versioning" $ do it "Can get the version number of a record" $ versionNumber foo0 `shouldBe` 0 it "Can read versioned record fields if present at given version" $ sinceV2 foo2 `shouldBe` "hello" it "Can read versioned sum-type constructors if present at given version" $ sumType `shouldBe` MkFoo () describe "Upgrade" $ do it "Can upgrade across two versions" $ upgrade foo0 `shouldBe` foo2 describe "Downgrade" $ do it "Can downgrade across two versions" $ downgrade foo2 `shouldBe` foo0 describe "DecodeAnyVersion" $ do it "Can decode from V0" $ fromJsonAnyVersion @V2 fooJsonV0 `shouldBe` Just foo2 it "Can decode from V2" $ fromJsonAnyVersion @V2 fooJsonV2 `shouldBe` Just foo2 describe "DecodeAnyVersionFrom" $ do it "Can decode from V1" $ fromJsonAnyVersionFrom @V1 @V2 fooJsonV2 `shouldBe` Just foo2 it "Should not decode V0" $ fromJsonAnyVersionFrom @V1 @V2 fooJsonV0 `shouldBe` (Nothing :: Maybe (Foo V2)) describe "WithAnyVersion" $ do -- Decode a Foo and return its string representation without upgrading it it "Can apply a function on the decoded object" $ do let Just res = withJsonAnyVersion @Show @Foo @V2 show fooJsonV0 res `shouldBe` show foo0 describe "WithAnyVersionFrom" $ do it "Can apply a function on the decoded object" $ do let Just res = withJsonAnyVersionFrom @V1 @Show @Foo @V2 show fooJsonV2 res `shouldBe` show foo2 it "Should not decode V0" $ do let res = withJsonAnyVersionFrom @V1 @Show @Foo @V2 show fooJsonV0 res `shouldBe` (Nothing :: Maybe String)