cuddle-1.3.0.0: test/Test/Codec/CBOR/Cuddle/CDDL/Validator/Golden.hs
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
module Test.Codec.CBOR.Cuddle.CDDL.Validator.Golden (spec) where
import Codec.CBOR.Cuddle.CBOR.Validator (validateCBOR)
import Codec.CBOR.Cuddle.CBOR.Validator.Trace (
defaultTraceOptions,
foldEvidenced,
prettyValidationTrace,
)
import Codec.CBOR.Cuddle.CDDL (Name)
import Codec.CBOR.Cuddle.CDDL.Resolve (fullResolveCDDL)
import Codec.CBOR.Cuddle.Huddle (Huddle, toCDDL)
import Codec.CBOR.Cuddle.IndexMappable (mapCDDLDropExt, mapIndex)
import Codec.CBOR.Term (Term (..), encodeTerm)
import Codec.CBOR.Write (toStrictByteString)
import Codec.CBOR.Write qualified as CBOR
import Control.Monad ((<=<))
import Data.Either (fromRight)
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Paths_cuddle (getDataFileName)
import Prettyprinter (defaultLayoutOptions, layoutPretty)
import Prettyprinter.Render.Terminal qualified as Ansi
import System.FilePath ((</>))
import Test.Codec.CBOR.Cuddle.CDDL.Examples.Huddle (
cborControlExample,
choicesExample,
deeplyNestedRefExample,
huddleRangeArray,
listSkippedRuleExample,
listSkippedRuleNestedExample,
listTooShortExample,
listZeroOrMoreExample,
mapLeftoverKVExample,
mapNestedValueExample,
mapNoMatchingKeyExample,
refTermExample,
)
import Test.Hspec (Spec, describe, it)
import Test.Hspec.Golden (Golden (..))
listTooShortTerm :: Term
listTooShortTerm = TList [TInt 42]
huddleRangeArrayTermTwoStrings :: Term
huddleRangeArrayTermTwoStrings =
TList
[ TInt 0
, TInt 1
, TString "one"
, TString "two"
]
refTermTooLong :: Term
refTermTooLong =
TList
[ TInt 0
, TList
[ TInt 1
, TInt 2
, TInt 3
, TInt 4
]
]
choiceAlmostSecond :: Term
choiceAlmostSecond =
TList
[ TInt 1
, TBool True
, TInt 1
]
listSkippedRuleTerm :: Term
listSkippedRuleTerm = TList [TInt 1, TInt 2]
listSkippedRuleNestedTerm :: Term
listSkippedRuleNestedTerm = TList [TInt 1, TList [TInt 2, TInt 3]]
mapLeftoverKVTerm :: Term
mapLeftoverKVTerm = TMap [(TInt 2, TString "hello")]
mapNoMatchingKeyTerm :: Term
mapNoMatchingKeyTerm = TMap [(TInt 99, TString "hello")]
listZeroOrMoreTerm :: Term
listZeroOrMoreTerm = TList [TInt 1, TInt 2, TString "hello", TBool True]
mapNestedValueTerm :: Term
mapNestedValueTerm = TMap [(TInt 1, TList [TInt 2, TInt 3])]
cborControlBad :: Term
cborControlBad = TBytes . toStrictByteString $ encodeTerm (TList [TInt 1, TInt 2, TInt 4])
validatorPrettyGolden :: String -> Huddle -> Name -> Term -> Spec
validatorPrettyGolden testName huddle n term =
it testName $
Golden
{ goldenFile = "golden" </> testName <> ".txt"
, readFromFile = T.readFile <=< getDataFileName
, writeToFile = \fp txt -> getDataFileName fp >>= (`T.writeFile` txt)
, actualFile = Nothing
, output = str
, encodePretty = T.unpack
, failFirstTime = False
}
where
bs = CBOR.toStrictByteString $ encodeTerm term
treeRoot =
fromRight (error "Failed to resolve CDDL") . fullResolveCDDL . mapCDDLDropExt $
toCDDL huddle
str =
Ansi.renderStrict
. layoutPretty defaultLayoutOptions
. foldEvidenced (prettyValidationTrace defaultTraceOptions)
. validateCBOR bs n
$ mapIndex treeRoot
spec :: Spec
spec = describe "golden" $ do
describe "error messages" $ do
validatorPrettyGolden
"huddleRangeArrayTwoStrings"
huddleRangeArray
"a"
huddleRangeArrayTermTwoStrings
validatorPrettyGolden
"refTermTooLong"
refTermExample
"root"
refTermTooLong
validatorPrettyGolden
"choiceAlmostSecond"
choicesExample
"root"
choiceAlmostSecond
validatorPrettyGolden
"cborControlBad"
cborControlExample
"root"
cborControlBad
validatorPrettyGolden
"listTooShort"
listTooShortExample
"root"
listTooShortTerm
validatorPrettyGolden
"listSkippedRule"
listSkippedRuleExample
"root"
listSkippedRuleTerm
validatorPrettyGolden
"listSkippedRuleNested"
listSkippedRuleNestedExample
"root"
listSkippedRuleNestedTerm
validatorPrettyGolden
"mapLeftoverKV"
mapLeftoverKVExample
"root"
mapLeftoverKVTerm
validatorPrettyGolden
"mapNoMatchingKey"
mapNoMatchingKeyExample
"root"
mapNoMatchingKeyTerm
validatorPrettyGolden
"listZeroOrMore"
listZeroOrMoreExample
"root"
listZeroOrMoreTerm
validatorPrettyGolden
"mapNestedValue"
mapNestedValueExample
"root"
mapNestedValueTerm
-- Deeply nested refs competing against a rule that makes actual term
-- progress. The stacked refs should NOT win over real term progress.
validatorPrettyGolden
"deeplyNestedRefVsRealProgress"
deeplyNestedRefExample
"root"
(TList [TInt 1, TList [TInt 1, TString "hello"]])