nbparts-0.1.1.0: tests/Tests/Types/ManifestSpec.hs
module Tests.Types.ManifestSpec where
import Control.Arrow (left)
import Data.Aeson qualified as Aeson
import Data.Either qualified as Either
import Data.Text.Encoding qualified as Text
import Data.Version (Version (Version))
import Data.Yaml qualified as Yaml
import Hedgehog (Gen, forAll, tripping, (===))
import Hedgehog.Gen qualified as Gen
import Hedgehog.Range qualified as Range
import Nbparts.Types.Manifest
( Format (FormatJson, FormatMarkdown, FormatYaml),
Manifest
( Manifest,
metadataFormat,
nbpartsVersion,
outputsFormat,
sourcesFormat
),
currentNbpartsVersion,
defManifest,
)
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)
import Test.Hspec.Hedgehog (hedgehog)
genVersion :: Gen Version
genVersion = do
branches <- Gen.list (Range.linear 3 4) (Gen.int $ Range.linear 0 10)
pure $ Version branches []
genFormat :: Gen Format
genFormat = Gen.element [FormatYaml, FormatJson, FormatMarkdown]
genSourcesFormat :: Gen Format
genSourcesFormat = genFormat
genMetadataFormat :: Gen Format
genMetadataFormat = Gen.element [FormatYaml, FormatJson]
genOutputsFormat :: Gen Format
genOutputsFormat = Gen.element [FormatYaml, FormatJson]
genManifest :: Gen Manifest
genManifest = do
nbpartsVersion <- genVersion
sourcesFormat <- genSourcesFormat
metadataFormat <- genMetadataFormat
outputsFormat <- genOutputsFormat
pure $
Manifest
{ nbpartsVersion,
sourcesFormat,
metadataFormat,
outputsFormat
}
spec :: Spec
spec = do
describe "Manifest" $ do
it "JSON roundtrip" $ hedgehog $ do
manifest <- forAll genManifest
tripping manifest Aeson.encode Aeson.decode
it "YAML roundtrip" $ hedgehog $ do
manifest <- forAll genManifest
tripping manifest Yaml.encode (left (const ()) . Yaml.decodeEither')
it "defManifest has correct nbpartsVersion" $ hedgehog $ do
let Manifest {nbpartsVersion} = defManifest
nbpartsVersion === currentNbpartsVersion
describe "Format" $ do
it "JSON roundtrip" $ hedgehog $ do
fmt <- forAll genFormat
tripping fmt Aeson.encode Aeson.decode
it "YAML roundtrip" $ hedgehog $ do
fmt <- forAll genFormat
tripping fmt Yaml.encode (left (const ()) . Yaml.decodeEither')
-- v0.1.0.0 mistakenly serialised `FormatJson` as "FormatJson" instead of "json",
-- so we're stuck dealing with that. Although the other formats were serialised correctly,
-- the "wrong" counterparts for them have been added for symmetry.
it "has backward compatibility with v0.1.0.0" $ do
Aeson.eitherDecodeStrict @Format (Text.encodeUtf8 "\"FormatYaml\"") `shouldBe` Right FormatYaml
left (const ()) (Yaml.decodeEither' @Format (Text.encodeUtf8 "\"FormatYaml\"")) `shouldBe` Right FormatYaml
Aeson.eitherDecodeStrict @Format (Text.encodeUtf8 "\"FormatJson\"") `shouldSatisfy` Either.isRight
left (const ()) (Yaml.decodeEither' @Format (Text.encodeUtf8 "\"FormatJson\"")) `shouldBe` Right FormatJson
Aeson.eitherDecodeStrict @Format (Text.encodeUtf8 "\"FormatMarkdown\"") `shouldSatisfy` Either.isRight
left (const ()) (Yaml.decodeEither' @Format (Text.encodeUtf8 "\"FormatMarkdown\"")) `shouldBe` Right FormatMarkdown