keiro-dsl-0.18.0.0: test/conformance-calendar-days/Generated/CalendarDays/Structural/CodecCompare/MaybeLocalDay.hs
-- @generated by keiro-dsl codec comparison; non-production migration evidence; do not edit.
-- This module compares historical and generated codecs in consumer-owned tests only.
-- It is never a runtime fallback and never changes the generated codec's authority.
module Generated.CalendarDays.Structural.CodecCompare.MaybeLocalDay (compareWithHistorical) where
import Control.Monad (filterM)
import Data.Aeson (Value)
import Data.Aeson qualified as Aeson
import Data.List (sort)
import Data.List.NonEmpty qualified as NonEmpty
import Data.Text (Text)
import Data.Text qualified
import Generated.CalendarDays.CalendarStore.Codec qualified as GeneratedCodec
import Keiro.Codec.Structural (FixtureCases (..))
import Keiro.Dsl.CodecCompare
import Keiro.Dsl.TypeGraph (BindingVersion (..), CanonicalTypeId (..), QualifiedValueName (..))
import System.Directory (doesFileExist, listDirectory)
import System.FilePath (takeExtension, (</>))
import Conformance.CalendarDays.Bindings qualified as Bindings
import Conformance.CalendarDays.Domain (MaybeLocalDay)
compareWithHistorical :: HistoricalCodec MaybeLocalDay -> FilePath -> IO CompareReport
compareWithHistorical historicalCodec goldenDirectory = do
names <- sort . filter ((== ".json") . takeExtension) <$> listDirectory goldenDirectory
files <- filterM doesFileExist [goldenDirectory </> name | name <- names]
loaded <- traverse (loadGolden historicalCodec) files
let inputIssues = [issue | Left issue <- loaded]
entries = [entry | Right entry <- loaded]
typedCases = NonEmpty.toList (fixtureCases Bindings.maybeLocalDayFixtures)
encodeObservations =
[ EncodeObservation label (historicalCodec.encode value) (GeneratedCodec.encodeMaybeLocalDayMapped value)
| (label, value) <- typedCases
]
decodeObservations = [observation | (observation, _) <- entries]
typedObserved =
concat
[ observedBranchesFor FromBinding branchSchema (GeneratedCodec.encodeMaybeLocalDayMapped value)
| (_, value) <- typedCases
]
historicalObserved =
concat [observedBranchesFor HistoricalGolden branchSchema value | (_, values) <- entries, value <- values]
declared = declaredBranchesFor FromBinding branchSchema <> declaredBranchesFor HistoricalGolden branchSchema
provenance =
CompareProvenance
{ historicalCodecIdentity = historicalCodec.identity
, historicalCodecVersion = historicalCodec.version
, canonicalType = CanonicalTypeId "conformance.calendar-days.MaybeLocalDay.v1"
, bindingSymbol = QualifiedValueName "Conformance.CalendarDays.Bindings.maybeLocalDayBinding"
, bindingVersion = BindingVersion "1"
, wireFingerprint = "c28177c9398266fc"
}
pure (compareReport provenance inputIssues (encodeObservations <> decodeObservations) declared (typedObserved <> historicalObserved))
loadGolden :: HistoricalCodec MaybeLocalDay -> FilePath -> IO (Either CompareInputIssue (CompareObservation, [Value]))
loadGolden historicalCodec path = do
decoded <- Aeson.eitherDecodeFileStrict path
pure $ case decoded of
Left reason -> Left (HistoricalGoldenUnreadable path (fromString reason))
Right inputValue ->
let historicalDecoded = historicalCodec.decode inputValue
historicalOutcome = normalizeDecode historicalDecoded
generatedOutcome = normalizeDecode (GeneratedCodec.decodeMaybeLocalDayMapped inputValue)
observation = DecodeObservation path inputValue historicalOutcome generatedOutcome
coveredValues = case historicalDecoded of
Right value -> [inputValue, GeneratedCodec.encodeMaybeLocalDayMapped value]
Left _ -> []
in Right (observation, coveredValues)
normalizeDecode :: Either Text MaybeLocalDay -> DecodeOutcome
normalizeDecode = either DecodeFailed (DecodedShape . GeneratedCodec.encodeMaybeLocalDayMapped)
fromString :: String -> Text
fromString = Data.Text.pack
branchSchema :: BranchSchema
branchSchema = BranchOptional (BranchScalar)