hydra-0.14.0: src/main/haskell/Hydra/Dsl/Meta/Testing.hs
{-# LANGUAGE FlexibleContexts #-}
-- | Meta-DSL for constructing test-related terms
-- TODO: merge with Hydra.Dsl.Tests
module Hydra.Dsl.Meta.Testing (
module Hydra.Dsl.Testing,
module Hydra.Dsl.Meta.Testing,
) where
import Hydra.Dsl.Testing hiding (
alphaConversionTestCase, caseConversionTestCase, deannotateTermTestCase,
deannotateTypeTestCase, delegatedEvaluationTestCase, etaExpansionTestCase,
evaluationStyleEager, evaluationStyleLazy, evaluationTestCase,
flattenLetTermsTestCase, foldOverTermTestCase, freeVariablesTestCase,
hoistCaseStatementsTestCase, hoistLetBindingsTestCase,
hoistPolymorphicLetBindingsTestCase, hoistPredicateApplications,
hoistPredicateCaseStatements, hoistPredicateLists, hoistPredicateNothing,
hoistSubtermsTestCase, inferenceFailureTestCase, inferenceTestCase,
joinTypesTestCase, jsonDecodeTestCase, jsonEncodeTestCase,
jsonRoundtripTestCase, liftLambdaAboveLetTestCase, normalizeTypeVariablesTestCase,
parserTestCase, rewriteTermTestCase, rewriteTypeTestCase,
serializationTestCase, simplifyTermTestCase, substInTypeTestCase, tag,
termRewriterReplaceFooWithBar, termRewriterReplaceInt32WithInt64,
testCaseAlphaConversion, testCaseCaseConversion, testCaseDeannotateTerm,
testCaseDeannotateType, testCaseDelegatedEvaluation, testCaseEtaExpansion,
testCaseEvaluation, testCaseFlattenLetTerms, testCaseFoldOverTerm,
testCaseFreeVariables, testCaseHoistCaseStatements, testCaseHoistLetBindings,
testCaseHoistPolymorphicLetBindings, testCaseHoistSubterms, testCaseInference,
testCaseInferenceFailure, testCaseJoinTypes, testCaseJsonDecode,
testCaseJsonEncode, testCaseJsonParser, testCaseJsonRoundtrip, testCaseJsonWriter,
testCaseLiftLambdaAboveLet, testCaseNormalizeTypeVariables, testCaseRewriteTerm,
testCaseRewriteType, testCaseSerialization, testCaseSimplifyTerm,
testCaseSubstInType, testCaseTopologicalSort, testCaseTopologicalSortBindings,
testCaseTopologicalSortSCC, testCaseTypeReduction, testCaseUnifyTypes,
testCaseUnshadowVariables, testCaseVariableOccursInType, testCaseWithMetadata,
testCaseWithMetadataCase, testCaseWithMetadataDescription,
testCaseWithMetadataName, testCaseWithMetadataTags, testGroup,
topologicalSortBindingsTestCase, topologicalSortSCCTestCase,
topologicalSortTestCase, typeReductionTestCase,
typeRewriterReplaceStringWithInt32, unifyTypesTestCase,
unshadowVariablesTestCase, variableOccursInTypeTestCase, writerTestCase, unTag,
testCaseTypeChecking, testCaseValidateCoreTerm, typeCheckingTestCase,
validateCoreTermCase, validateCoreTermTestCase)
import Hydra.Kernel
import Hydra.Ast (Expr)
import Hydra.Json.Model (Value)
import Hydra.Parsing (ParseResult)
import Hydra.Testing as Testing
import Hydra.Dsl.Meta.Phantoms as Phantoms hiding ((++))
import qualified Hydra.Encode.Core as EncodeCore
import qualified Hydra.Dsl.Meta.Core as Core
import qualified Hydra.Dsl.Terms as Terms
import qualified Hydra.Dsl.Meta.Terms as MetaTerms
import qualified Hydra.Dsl.Meta.Types as T
import qualified Data.Int as I
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
type Int32 = I.Int32
tag_disabled = Tag "disabled"
tag_disabledForMinimalInference = Tag "disabledForMinimalInference"
noTags :: TTerm [Tag]
noTags = Phantoms.list ([] :: [TTerm Tag])
expectFailure :: AsTerm t Term => Int -> [Tag] -> t -> TTerm TestCaseWithMetadata
expectFailure i tags term = infFailureTest ("#" ++ show i) tags (asTerm term)
expectMono :: AsTerm t Term => Int -> [Tag] -> t -> TTerm Type -> TTerm TestCaseWithMetadata
expectMono i tags term typ = infTest ("#" ++ show i) tags (asTerm term) $ T.mono typ
expectPoly :: AsTerm t Term => Int -> [Tag] -> t -> [String] -> TTerm Type -> TTerm TestCaseWithMetadata
expectPoly i tags term params typ = infTest ("#" ++ show i) tags (asTerm term) $ T.poly params typ
expectPolyConstrained :: AsTerm t Term => Int -> [Tag] -> t -> [String] -> [(String, [String])] -> TTerm Type -> TTerm TestCaseWithMetadata
expectPolyConstrained i tags term params constraints typ = infTest ("#" ++ show i) tags (asTerm term) $ T.polyConstrained params constraints typ
groupRef = MetaTerms.varNamePhantom . bindingName
primCase :: String -> Name -> [TTerm Term] -> TTerm Term -> TTerm TestCaseWithMetadata
primCase cname primName args output = primCaseWithTags cname [] primName args output
primCaseWithTags :: String -> [Tag] -> Name -> [TTerm Term] -> TTerm Term -> TTerm TestCaseWithMetadata
primCaseWithTags cname tags primName args output = testCaseWithMetadata (Phantoms.string cname)
(testCaseEvaluation $ evaluationTestCase evaluationStyleEager input output)
nothing (Phantoms.list $ tag . unTag <$> tags)
where
input = L.foldl (MetaTerms.@@) (MetaTerms.primitive primName) args
evalCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
evalCase cname input output = evalCaseWithTags cname [] input output
evalCaseWithTags :: String -> [Tag] -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
evalCaseWithTags cname tags input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseEvaluation $ evaluationTestCase evaluationStyleEager input output)
nothing (Phantoms.list $ tag . unTag <$> tags)
infFailureTest :: String -> [Tag] -> TTerm Term -> TTerm TestCaseWithMetadata
infFailureTest name tags term = testCaseWithMetadata (Phantoms.string name)
(testCaseInferenceFailure $ inferenceFailureTestCase term) nothing (Phantoms.list $ tag . unTag <$> tags)
infTest :: String -> [Tag] -> TTerm Term -> TTerm TypeScheme -> TTerm TestCaseWithMetadata
infTest name tags term ts = testCaseWithMetadata (Phantoms.string name)
(testCaseInference $ inferenceTestCase term ts) nothing (Phantoms.list $ tag . unTag <$> tags)
isDisabled tcase = tag_disabled `L.elem` Testing.testCaseWithMetadataTags tcase
isDisabledForMinimalInference tcase = tag_disabledForMinimalInference `L.elem` Testing.testCaseWithMetadataTags tcase
mapTerm :: [(TTerm Term, TTerm Term)] -> TTerm Term
mapTerm pairs = TTerm $ TermUnion $ Injection _Term $ Field _Term_map $ TermMap $ M.fromList [(unTTerm k, unTTerm v) | (k, v) <- pairs]
mapTermEmpty :: TTerm (M.Map k v)
mapTermEmpty = TTerm $ TermMap M.empty
subgroup :: AsTerm t TestCaseWithMetadata => String -> [t] -> TTerm TestGroup
subgroup name cases = tgroup name Nothing [] (asTerm <$> cases)
supergroup :: AsTerm t TestGroup => String -> [t] -> TTerm TestGroup
supergroup name subgroups = tgroup name Nothing (asTerm <$> subgroups) []
tag :: String -> TTerm Tag
tag = Phantoms.wrap _Tag . Phantoms.string
tgroup :: String -> Maybe String -> [TTerm TestGroup] -> [TTerm TestCaseWithMetadata] -> TTerm TestGroup
tgroup name mdesc subgroups cases = testGroup (Phantoms.string name) (opt (Phantoms.string <$> mdesc)) (Phantoms.list subgroups) (Phantoms.list cases)
----------------------------------------
encodeGroup (TestGroup name desc groups cases) = Terms.record _TestGroup [
Field _TestGroup_name $ Terms.string name,
Field _TestGroup_description $ Terms.optional (Terms.string <$> desc),
Field _TestGroup_subgroups $ Terms.list (encodeGroup <$> groups),
Field _TestGroup_cases $ Terms.list (encodeCaseWithMetadata <$> cases)]
encodeCaseWithMetadata (TestCaseWithMetadata name tcase mdesc tags) = Terms.record _TestCaseWithMetadata [
Field _TestCaseWithMetadata_name $ Terms.string name,
Field _TestCaseWithMetadata_case $ encodeCase tcase,
Field _TestCaseWithMetadata_description $ Terms.optional (Terms.string <$> mdesc),
Field _TestCaseWithMetadata_tags $ Terms.list (Terms.string . unTag <$> tags)]
encodeCase tcase = case tcase of
TestCaseCaseConversion ccase -> Terms.inject _TestCase _TestCase_caseConversion $ encodeCaseConversionTestCase ccase
TestCaseEtaExpansion ecase -> Terms.inject _TestCase _TestCase_etaExpansion $ encodeEtaExpansionTestCase ecase
TestCaseEvaluation ecase -> Terms.inject _TestCase _TestCase_evaluation $ encodeEvaluationTestCase ecase
TestCaseInference icase -> Terms.inject _TestCase _TestCase_inference $ encodeInferenceTestCase icase
encodeCaseConvention c = Terms.injectUnit _CaseConvention $ case c of
CaseConventionLowerSnake -> _CaseConvention_lowerSnake
CaseConventionUpperSnake -> _CaseConvention_upperSnake
CaseConventionCamel -> _CaseConvention_camel
CaseConventionPascal -> _CaseConvention_pascal
encodeCaseConversionTestCase (CaseConversionTestCase fromConvention toConvention fromString toString) = Terms.record _CaseConversionTestCase [
Field _CaseConversionTestCase_fromConvention $ encodeCaseConvention fromConvention,
Field _CaseConversionTestCase_toConvention $ encodeCaseConvention toConvention,
Field _CaseConversionTestCase_fromString $ Terms.string fromString,
Field _CaseConversionTestCase_toString $ Terms.string toString]
encodeEtaExpansionTestCase (EtaExpansionTestCase input output) = Terms.record _EtaExpansionTestCase [
Field _EtaExpansionTestCase_input $ EncodeCore.term input,
Field _EtaExpansionTestCase_output $ EncodeCore.term output]
encodeEvaluationTestCase (EvaluationTestCase style input output) = Terms.record _EvaluationTestCase [
Field _EvaluationTestCase_evaluationStyle $ Terms.inject _EvaluationStyle (case style of
EvaluationStyleEager -> _EvaluationStyle_eager
EvaluationStyleLazy -> _EvaluationStyle_lazy) Terms.unit,
Field _EvaluationTestCase_input $ EncodeCore.term input,
Field _EvaluationTestCase_output $ EncodeCore.term output]
encodeInferenceTestCase (InferenceTestCase input output) = Terms.record _InferenceTestCase [
Field _InferenceTestCase_input $ EncodeCore.term input,
Field _InferenceTestCase_output $ EncodeCore.typeScheme output]
----------------------------------------
caseConversionTestCase :: TTerm CaseConvention -> TTerm CaseConvention -> TTerm String -> TTerm String -> TTerm CaseConversionTestCase
caseConversionTestCase fromConvention toConvention fromString toString =
Phantoms.record _CaseConversionTestCase [
_CaseConversionTestCase_fromConvention>>: fromConvention,
_CaseConversionTestCase_toConvention>>: toConvention,
_CaseConversionTestCase_fromString>>: fromString,
_CaseConversionTestCase_toString>>: toString]
encodedTestGroupToBinding :: Namespace -> String -> TTerm TestGroup -> Binding
encodedTestGroupToBinding ns lname group = Binding name (unTTerm group)
$ Just $ TypeScheme [] typ Nothing
where
name = unqualifyName $ QualifiedName (Just ns) lname
typ = TypeVariable _TestGroup
inferenceFailureTestCase :: TTerm Term -> TTerm InferenceFailureTestCase
inferenceFailureTestCase input = Phantoms.record _InferenceFailureTestCase [
_InferenceFailureTestCase_input>>: input]
etaExpansionTestCase :: TTerm Term -> TTerm Term -> TTerm EtaExpansionTestCase
etaExpansionTestCase input output = Phantoms.record _EtaExpansionTestCase [
_EtaExpansionTestCase_input>>: input,
_EtaExpansionTestCase_output>>: output]
inferenceTestCase :: TTerm Term -> TTerm TypeScheme -> TTerm InferenceTestCase
inferenceTestCase input output = Phantoms.record _InferenceTestCase [
_InferenceTestCase_input>>: input,
_InferenceTestCase_output>>: output]
evaluationStyleEager :: TTerm EvaluationStyle
evaluationStyleEager = Phantoms.injectUnit _EvaluationStyle _EvaluationStyle_eager
evaluationStyleLazy :: TTerm EvaluationStyle
evaluationStyleLazy = Phantoms.injectUnit _EvaluationStyle _EvaluationStyle_lazy
evaluationTestCase :: TTerm EvaluationStyle -> TTerm Term -> TTerm Term -> TTerm EvaluationTestCase
evaluationTestCase style input output = Phantoms.record _EvaluationTestCase [
_EvaluationTestCase_evaluationStyle>>: style,
_EvaluationTestCase_input>>: input,
_EvaluationTestCase_output>>: output]
delegatedEvaluationTestCase :: TTerm Term -> TTerm Term -> TTerm DelegatedEvaluationTestCase
delegatedEvaluationTestCase input output = Phantoms.record _DelegatedEvaluationTestCase [
_DelegatedEvaluationTestCase_input>>: input,
_DelegatedEvaluationTestCase_output>>: output]
testCaseCaseConversion :: TTerm CaseConversionTestCase -> TTerm TestCase
testCaseCaseConversion = inject _TestCase _TestCase_caseConversion
testCaseDelegatedEvaluation :: TTerm DelegatedEvaluationTestCase -> TTerm TestCase
testCaseDelegatedEvaluation = inject _TestCase _TestCase_delegatedEvaluation
testCaseEtaExpansion :: TTerm EtaExpansionTestCase -> TTerm TestCase
testCaseEtaExpansion = inject _TestCase _TestCase_etaExpansion
testCaseEvaluation :: TTerm EvaluationTestCase -> TTerm TestCase
testCaseEvaluation = inject _TestCase _TestCase_evaluation
testCaseInference :: TTerm InferenceTestCase -> TTerm TestCase
testCaseInference = inject _TestCase _TestCase_inference
testCaseInferenceFailure :: TTerm InferenceFailureTestCase -> TTerm TestCase
testCaseInferenceFailure = inject _TestCase _TestCase_inferenceFailure
testCaseJsonDecode :: TTerm JsonDecodeTestCase -> TTerm TestCase
testCaseJsonDecode = inject _TestCase _TestCase_jsonDecode
testCaseJsonEncode :: TTerm JsonEncodeTestCase -> TTerm TestCase
testCaseJsonEncode = inject _TestCase _TestCase_jsonEncode
testCaseJsonParser :: TTerm JsonParserTestCase -> TTerm TestCase
testCaseJsonParser = inject _TestCase _TestCase_jsonParser
testCaseJsonRoundtrip :: TTerm JsonRoundtripTestCase -> TTerm TestCase
testCaseJsonRoundtrip = inject _TestCase _TestCase_jsonRoundtrip
testCaseJsonWriter :: TTerm JsonWriterTestCase -> TTerm TestCase
testCaseJsonWriter = inject _TestCase _TestCase_jsonWriter
testCaseAlphaConversion :: TTerm AlphaConversionTestCase -> TTerm TestCase
testCaseAlphaConversion = inject _TestCase _TestCase_alphaConversion
testCaseTypeReduction :: TTerm TypeReductionTestCase -> TTerm TestCase
testCaseTypeReduction = inject _TestCase _TestCase_typeReduction
alphaConversionTestCase :: TTerm Term -> TTerm Name -> TTerm Name -> TTerm Term -> TTerm AlphaConversionTestCase
alphaConversionTestCase term oldVar newVar result = Phantoms.record _AlphaConversionTestCase [
_AlphaConversionTestCase_term>>: term,
_AlphaConversionTestCase_oldVariable>>: oldVar,
_AlphaConversionTestCase_newVariable>>: newVar,
_AlphaConversionTestCase_result>>: result]
typeReductionTestCase :: TTerm Type -> TTerm Type -> TTerm TypeReductionTestCase
typeReductionTestCase input output = Phantoms.record _TypeReductionTestCase [
_TypeReductionTestCase_input>>: input,
_TypeReductionTestCase_output>>: output]
-- | Convenience function for creating alpha conversion test cases
alphaCase :: String -> TTerm Term -> TTerm Name -> TTerm Name -> TTerm Term -> TTerm TestCaseWithMetadata
alphaCase cname term oldVar newVar result = testCaseWithMetadata (Phantoms.string cname)
(testCaseAlphaConversion $ alphaConversionTestCase term oldVar newVar result)
nothing noTags
-- | Convenience function for creating type reduction test cases
typeRedCase :: String -> TTerm Type -> TTerm Type -> TTerm TestCaseWithMetadata
typeRedCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseTypeReduction $ typeReductionTestCase input output)
nothing noTags
writerTestCase :: TTerm a -> TTerm String -> TTerm (WriterTestCase a)
writerTestCase input output = Phantoms.record _WriterTestCase [
_WriterTestCase_input>>: input,
_WriterTestCase_output>>: output]
jsonWriterTestCase :: TTerm Value -> TTerm String -> TTerm JsonWriterTestCase
jsonWriterTestCase = writerTestCase
parserTestCase :: TTerm String -> TTerm (ParseResult a) -> TTerm (ParserTestCase a)
parserTestCase input output = Phantoms.record _ParserTestCase [
_ParserTestCase_input>>: input,
_ParserTestCase_output>>: output]
jsonParserTestCase :: TTerm String -> TTerm (ParseResult Value) -> TTerm JsonParserTestCase
jsonParserTestCase = parserTestCase
----------------------------------------
-- JSON encode/decode/roundtrip test case helpers (Either-based)
jsonDecodeTestCase :: TTerm Type -> TTerm Value -> TTerm (Either String Term) -> TTerm JsonDecodeTestCase
jsonDecodeTestCase typ json expected = Phantoms.record _JsonDecodeTestCase [
_JsonDecodeTestCase_type>>: typ,
_JsonDecodeTestCase_json>>: json,
_JsonDecodeTestCase_expected>>: expected]
jsonEncodeTestCase :: TTerm Term -> TTerm (Either String Value) -> TTerm JsonEncodeTestCase
jsonEncodeTestCase term expected = Phantoms.record _JsonEncodeTestCase [
_JsonEncodeTestCase_term>>: term,
_JsonEncodeTestCase_expected>>: expected]
jsonRoundtripTestCase :: TTerm Type -> TTerm Term -> TTerm JsonRoundtripTestCase
jsonRoundtripTestCase typ term = Phantoms.record _JsonRoundtripTestCase [
_JsonRoundtripTestCase_type>>: typ,
_JsonRoundtripTestCase_term>>: term]
-- | Convenience function for creating JSON decode test cases (Either-based)
jsonDecodeCase :: String -> TTerm Type -> TTerm Value -> TTerm (Either String Term) -> TTerm TestCaseWithMetadata
jsonDecodeCase cname typ json expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseJsonDecode $ jsonDecodeTestCase typ json expected)
nothing noTags
-- | Convenience function for creating JSON encode test cases (Either-based)
jsonEncodeCase :: String -> TTerm Term -> TTerm (Either String Value) -> TTerm TestCaseWithMetadata
jsonEncodeCase cname term expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseJsonEncode $ jsonEncodeTestCase term expected)
nothing noTags
-- | Convenience function for creating JSON round-trip test cases (Either-based)
jsonRoundtripCase :: String -> TTerm Type -> TTerm Term -> TTerm TestCaseWithMetadata
jsonRoundtripCase cname typ term = testCaseWithMetadata (Phantoms.string cname)
(testCaseJsonRoundtrip $ jsonRoundtripTestCase typ term)
nothing noTags
testCaseTopologicalSort :: TTerm TopologicalSortTestCase -> TTerm TestCase
testCaseTopologicalSort = inject _TestCase _TestCase_topologicalSort
testCaseTopologicalSortSCC :: TTerm TopologicalSortSCCTestCase -> TTerm TestCase
testCaseTopologicalSortSCC = inject _TestCase _TestCase_topologicalSortSCC
topologicalSortTestCase :: TTerm [(Int, [Int])] -> TTerm (Either [[Int]] [Int]) -> TTerm TopologicalSortTestCase
topologicalSortTestCase adj expected = Phantoms.record _TopologicalSortTestCase [
_TopologicalSortTestCase_adjacencyList>>: adj,
_TopologicalSortTestCase_expected>>: expected]
topologicalSortSCCTestCase :: TTerm [(Int, [Int])] -> TTerm [[Int]] -> TTerm TopologicalSortSCCTestCase
topologicalSortSCCTestCase adj expected = Phantoms.record _TopologicalSortSCCTestCase [
_TopologicalSortSCCTestCase_adjacencyList>>: adj,
_TopologicalSortSCCTestCase_expected>>: expected]
-- | Convenience function for creating topological sort test cases
sortCase :: String -> TTerm [(Int, [Int])] -> TTerm (Either [[Int]] [Int]) -> TTerm TestCaseWithMetadata
sortCase cname adj expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseTopologicalSort $ topologicalSortTestCase adj expected)
nothing noTags
-- | Convenience function for creating topological sort SCC test cases
sortSCCCase :: String -> TTerm [(Int, [Int])] -> TTerm [[Int]] -> TTerm TestCaseWithMetadata
sortSCCCase cname adj expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseTopologicalSortSCC $ topologicalSortSCCTestCase adj expected)
nothing noTags
testCaseWithMetadata :: TTerm String -> TTerm TestCase -> TTerm (Maybe String) -> TTerm [Tag] -> TTerm TestCaseWithMetadata
testCaseWithMetadata name tcase description tags = Phantoms.record _TestCaseWithMetadata [
_TestCaseWithMetadata_name>>: name,
_TestCaseWithMetadata_case>>: tcase,
_TestCaseWithMetadata_description>>: description,
_TestCaseWithMetadata_tags>>: tags]
testCaseWithMetadataName :: TTerm (TestCaseWithMetadata -> String)
testCaseWithMetadataName = Phantoms.project _TestCaseWithMetadata _TestCaseWithMetadata_name
testCaseWithMetadataCase :: TTerm (TestCaseWithMetadata -> TestCase)
testCaseWithMetadataCase = Phantoms.project _TestCaseWithMetadata _TestCaseWithMetadata_case
testCaseWithMetadataDescription :: TTerm (TestCaseWithMetadata -> Maybe String)
testCaseWithMetadataDescription = Phantoms.project _TestCaseWithMetadata _TestCaseWithMetadata_description
testCaseWithMetadataTags :: TTerm (TestCaseWithMetadata -> [Tag])
testCaseWithMetadataTags = Phantoms.project _TestCaseWithMetadata _TestCaseWithMetadata_tags
testGroup :: TTerm String -> TTerm (Maybe String) -> TTerm [TestGroup] -> TTerm [TestCaseWithMetadata] -> TTerm TestGroup
testGroup name description subgroups cases = Phantoms.record _TestGroup [
_TestGroup_name>>: name,
_TestGroup_description>>: description,
_TestGroup_subgroups>>: subgroups,
_TestGroup_cases>>: cases]
testGroupToBinding :: Namespace -> String -> TestGroup -> Binding
testGroupToBinding ns lname group = encodedTestGroupToBinding ns lname (TTerm $ encodeGroup group)
testCaseSerialization :: TTerm SerializationTestCase -> TTerm TestCase
testCaseSerialization = inject _TestCase _TestCase_serialization
serializationTestCase :: TTerm Expr -> TTerm String -> TTerm SerializationTestCase
serializationTestCase input output = Phantoms.record _SerializationTestCase [
_SerializationTestCase_input>>: input,
_SerializationTestCase_output>>: output]
-- | Convenience function for creating serialization test cases
serCase :: String -> TTerm Expr -> TTerm String -> TTerm TestCaseWithMetadata
serCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseSerialization $ serializationTestCase input output)
nothing noTags
----------------------------------------
-- Rewriting test case helpers
testCaseFlattenLetTerms :: TTerm FlattenLetTermsTestCase -> TTerm TestCase
testCaseFlattenLetTerms = inject _TestCase _TestCase_flattenLetTerms
testCaseFreeVariables :: TTerm FreeVariablesTestCase -> TTerm TestCase
testCaseFreeVariables = inject _TestCase _TestCase_freeVariables
testCaseLiftLambdaAboveLet :: TTerm LiftLambdaAboveLetTestCase -> TTerm TestCase
testCaseLiftLambdaAboveLet = inject _TestCase _TestCase_liftLambdaAboveLet
testCaseSimplifyTerm :: TTerm SimplifyTermTestCase -> TTerm TestCase
testCaseSimplifyTerm = inject _TestCase _TestCase_simplifyTerm
flattenLetTermsTestCase :: TTerm Term -> TTerm Term -> TTerm FlattenLetTermsTestCase
flattenLetTermsTestCase input output = Phantoms.record _FlattenLetTermsTestCase [
_FlattenLetTermsTestCase_input>>: input,
_FlattenLetTermsTestCase_output>>: output]
freeVariablesTestCase :: TTerm Term -> TTerm (S.Set Name) -> TTerm FreeVariablesTestCase
freeVariablesTestCase input output = Phantoms.record _FreeVariablesTestCase [
_FreeVariablesTestCase_input>>: input,
_FreeVariablesTestCase_output>>: output]
liftLambdaAboveLetTestCase :: TTerm Term -> TTerm Term -> TTerm LiftLambdaAboveLetTestCase
liftLambdaAboveLetTestCase input output = Phantoms.record _LiftLambdaAboveLetTestCase [
_LiftLambdaAboveLetTestCase_input>>: input,
_LiftLambdaAboveLetTestCase_output>>: output]
simplifyTermTestCase :: TTerm Term -> TTerm Term -> TTerm SimplifyTermTestCase
simplifyTermTestCase input output = Phantoms.record _SimplifyTermTestCase [
_SimplifyTermTestCase_input>>: input,
_SimplifyTermTestCase_output>>: output]
-- | Convenience function for creating flatten let terms test cases
flattenCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
flattenCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseFlattenLetTerms $ flattenLetTermsTestCase input output)
nothing noTags
-- | Convenience function for creating free variables test cases
freeVarsCase :: String -> TTerm Term -> TTerm (S.Set Name) -> TTerm TestCaseWithMetadata
freeVarsCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseFreeVariables $ freeVariablesTestCase input output)
nothing noTags
-- | Convenience function for creating lift lambda above let test cases
liftLambdaCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
liftLambdaCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseLiftLambdaAboveLet $ liftLambdaAboveLetTestCase input output)
nothing noTags
-- | Convenience function for creating simplify term test cases
simplifyCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
simplifyCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseSimplifyTerm $ simplifyTermTestCase input output)
nothing noTags
----------------------------------------
-- Deannotate test case helpers
testCaseDeannotateTerm :: TTerm DeannotateTermTestCase -> TTerm TestCase
testCaseDeannotateTerm = inject _TestCase _TestCase_deannotateTerm
testCaseDeannotateType :: TTerm DeannotateTypeTestCase -> TTerm TestCase
testCaseDeannotateType = inject _TestCase _TestCase_deannotateType
deannotateTermTestCase :: TTerm Term -> TTerm Term -> TTerm DeannotateTermTestCase
deannotateTermTestCase input output = Phantoms.record _DeannotateTermTestCase [
_DeannotateTermTestCase_input>>: input,
_DeannotateTermTestCase_output>>: output]
deannotateTypeTestCase :: TTerm Type -> TTerm Type -> TTerm DeannotateTypeTestCase
deannotateTypeTestCase input output = Phantoms.record _DeannotateTypeTestCase [
_DeannotateTypeTestCase_input>>: input,
_DeannotateTypeTestCase_output>>: output]
-- | Convenience function for creating deannotate term test cases
deannotateTermCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
deannotateTermCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseDeannotateTerm $ deannotateTermTestCase input output)
nothing noTags
-- | Convenience function for creating deannotate type test cases
deannotateTypeCase :: String -> TTerm Type -> TTerm Type -> TTerm TestCaseWithMetadata
deannotateTypeCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseDeannotateType $ deannotateTypeTestCase input output)
nothing noTags
----------------------------------------
-- Topological sort bindings test case helpers
testCaseTopologicalSortBindings :: TTerm TopologicalSortBindingsTestCase -> TTerm TestCase
testCaseTopologicalSortBindings = inject _TestCase _TestCase_topologicalSortBindings
topologicalSortBindingsTestCase :: TTerm [(Name, Term)] -> TTerm [[(Name, Term)]] -> TTerm TopologicalSortBindingsTestCase
topologicalSortBindingsTestCase bindings expected = Phantoms.record _TopologicalSortBindingsTestCase [
_TopologicalSortBindingsTestCase_bindings>>: bindings,
_TopologicalSortBindingsTestCase_expected>>: expected]
-- | Convenience function for creating topological sort bindings test cases
sortBindingsCase :: String -> TTerm [(Name, Term)] -> TTerm [[(Name, Term)]] -> TTerm TestCaseWithMetadata
sortBindingsCase cname bindings expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseTopologicalSortBindings $ topologicalSortBindingsTestCase bindings expected)
nothing noTags
----------------------------------------
-- Normalize type variables test case helpers
testCaseNormalizeTypeVariables :: TTerm NormalizeTypeVariablesTestCase -> TTerm TestCase
testCaseNormalizeTypeVariables = inject _TestCase _TestCase_normalizeTypeVariables
normalizeTypeVariablesTestCase :: TTerm Term -> TTerm Term -> TTerm NormalizeTypeVariablesTestCase
normalizeTypeVariablesTestCase input output = Phantoms.record _NormalizeTypeVariablesTestCase [
_NormalizeTypeVariablesTestCase_input>>: input,
_NormalizeTypeVariablesTestCase_output>>: output]
-- | Convenience function for creating normalize type variables test cases
normalizeTypeVarsCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
normalizeTypeVarsCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseNormalizeTypeVariables $ normalizeTypeVariablesTestCase input output)
nothing noTags
----------------------------------------
-- Fold over term test case helpers
testCaseFoldOverTerm :: TTerm FoldOverTermTestCase -> TTerm TestCase
testCaseFoldOverTerm = inject _TestCase _TestCase_foldOverTerm
foldOverTermTestCase :: TTerm Term -> TTerm TraversalOrder -> TTerm FoldOperation -> TTerm Term -> TTerm FoldOverTermTestCase
foldOverTermTestCase input order op output = Phantoms.record _FoldOverTermTestCase [
_FoldOverTermTestCase_input>>: input,
_FoldOverTermTestCase_traversalOrder>>: order,
_FoldOverTermTestCase_operation>>: op,
_FoldOverTermTestCase_output>>: output]
-- Fold operation constructors
foldOpSumInt32Literals :: TTerm FoldOperation
foldOpSumInt32Literals = inject _FoldOperation _FoldOperation_sumInt32Literals $ Phantoms.unit
foldOpCollectListLengths :: TTerm FoldOperation
foldOpCollectListLengths = inject _FoldOperation _FoldOperation_collectListLengths $ Phantoms.unit
foldOpCollectLabels :: TTerm FoldOperation
foldOpCollectLabels = inject _FoldOperation _FoldOperation_collectLabels $ Phantoms.unit
-- | Convenience function for creating fold over term test cases
foldOverTermCase :: String -> TTerm Term -> TTerm TraversalOrder -> TTerm FoldOperation -> TTerm Term -> TTerm TestCaseWithMetadata
foldOverTermCase cname input order op output = testCaseWithMetadata (Phantoms.string cname)
(testCaseFoldOverTerm $ foldOverTermTestCase input order op output)
nothing noTags
----------------------------------------
-- Rewrite term test case helpers
testCaseRewriteTerm :: TTerm RewriteTermTestCase -> TTerm TestCase
testCaseRewriteTerm = inject _TestCase _TestCase_rewriteTerm
rewriteTermTestCase :: TTerm Term -> TTerm TermRewriter -> TTerm Term -> TTerm RewriteTermTestCase
rewriteTermTestCase input rewriter output = Phantoms.record _RewriteTermTestCase [
_RewriteTermTestCase_input>>: input,
_RewriteTermTestCase_rewriter>>: rewriter,
_RewriteTermTestCase_output>>: output]
-- Term rewriter constructors
termRewriterReplaceFooWithBar :: TTerm TermRewriter
termRewriterReplaceFooWithBar = inject _TermRewriter _TermRewriter_replaceFooWithBar $ Phantoms.unit
termRewriterReplaceInt32WithInt64 :: TTerm TermRewriter
termRewriterReplaceInt32WithInt64 = inject _TermRewriter _TermRewriter_replaceInt32WithInt64 $ Phantoms.unit
-- | Convenience function for creating rewrite term test cases (replaceFooWithBar)
rewriteTermCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
rewriteTermCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseRewriteTerm $ rewriteTermTestCase input termRewriterReplaceFooWithBar output)
nothing noTags
----------------------------------------
-- Rewrite type test case helpers
testCaseRewriteType :: TTerm RewriteTypeTestCase -> TTerm TestCase
testCaseRewriteType = inject _TestCase _TestCase_rewriteType
rewriteTypeTestCase :: TTerm Type -> TTerm TypeRewriter -> TTerm Type -> TTerm RewriteTypeTestCase
rewriteTypeTestCase input rewriter output = Phantoms.record _RewriteTypeTestCase [
_RewriteTypeTestCase_input>>: input,
_RewriteTypeTestCase_rewriter>>: rewriter,
_RewriteTypeTestCase_output>>: output]
-- Type rewriter constructors
typeRewriterReplaceStringWithInt32 :: TTerm TypeRewriter
typeRewriterReplaceStringWithInt32 = inject _TypeRewriter _TypeRewriter_replaceStringWithInt32 $ Phantoms.unit
-- | Convenience function for creating rewrite type test cases (replaceStringWithInt32)
rewriteTypeCase :: String -> TTerm Type -> TTerm Type -> TTerm TestCaseWithMetadata
rewriteTypeCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseRewriteType $ rewriteTypeTestCase input typeRewriterReplaceStringWithInt32 output)
nothing noTags
-- | Convenience function for creating eta expansion test cases
etaCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
etaCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseEtaExpansion $ etaExpansionTestCase input output)
nothing noTags
----------------------------------------
-- Hoist subterms test case helpers
testCaseHoistSubterms :: TTerm HoistSubtermsTestCase -> TTerm TestCase
testCaseHoistSubterms = inject _TestCase _TestCase_hoistSubterms
hoistSubtermsTestCase :: TTerm HoistPredicate -> TTerm Term -> TTerm Term -> TTerm HoistSubtermsTestCase
hoistSubtermsTestCase predicate input output = Phantoms.record _HoistSubtermsTestCase [
_HoistSubtermsTestCase_predicate>>: predicate,
_HoistSubtermsTestCase_input>>: input,
_HoistSubtermsTestCase_output>>: output]
-- Hoist predicate constructors
-- | Hoist case statements (elimination unions) at non-top-level positions
hoistPredicateCaseStatements :: TTerm HoistPredicate
hoistPredicateCaseStatements = inject _HoistPredicate _HoistPredicate_caseStatements $ Phantoms.unit
-- | Hoist function applications at non-top-level positions
hoistPredicateApplications :: TTerm HoistPredicate
hoistPredicateApplications = inject _HoistPredicate _HoistPredicate_applications $ Phantoms.unit
-- | Hoist list terms at non-top-level positions
hoistPredicateLists :: TTerm HoistPredicate
hoistPredicateLists = inject _HoistPredicate _HoistPredicate_lists $ Phantoms.unit
-- | Never hoist anything (identity transformation)
hoistPredicateNothing :: TTerm HoistPredicate
hoistPredicateNothing = inject _HoistPredicate _HoistPredicate_nothing $ Phantoms.unit
-- | Convenience function for creating hoist subterms test cases
hoistCase :: String -> TTerm HoistPredicate -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
hoistCase cname predicate input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseHoistSubterms $ hoistSubtermsTestCase predicate input output)
nothing noTags
----------------------------------------
-- Hoist case statements test case helpers
testCaseHoistCaseStatements :: TTerm HoistCaseStatementsTestCase -> TTerm TestCase
testCaseHoistCaseStatements = inject _TestCase _TestCase_hoistCaseStatements
hoistCaseStatementsTestCase :: TTerm Term -> TTerm Term -> TTerm HoistCaseStatementsTestCase
hoistCaseStatementsTestCase input output = Phantoms.record _HoistCaseStatementsTestCase [
_HoistCaseStatementsTestCase_input>>: input,
_HoistCaseStatementsTestCase_output>>: output]
-- | Convenience function for creating hoist case statements test cases
hoistCaseStatementsCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
hoistCaseStatementsCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseHoistCaseStatements $ hoistCaseStatementsTestCase input output)
nothing noTags
-----------------------------------------
-- Hoist let bindings test case helpers (hoistAll=True, for Java)
testCaseHoistLetBindings :: TTerm HoistLetBindingsTestCase -> TTerm TestCase
testCaseHoistLetBindings = inject _TestCase _TestCase_hoistLetBindings
hoistLetBindingsTestCase :: TTerm Let -> TTerm Let -> TTerm HoistLetBindingsTestCase
hoistLetBindingsTestCase input output = Phantoms.record _HoistLetBindingsTestCase [
_HoistLetBindingsTestCase_input>>: input,
_HoistLetBindingsTestCase_output>>: output]
-- | Convenience function for creating hoist let bindings test cases
hoistLetBindingsCase :: String -> TTerm Let -> TTerm Let -> TTerm TestCaseWithMetadata
hoistLetBindingsCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseHoistLetBindings $ hoistLetBindingsTestCase input output)
nothing noTags
-----------------------------------------
-- Hoist polymorphic let bindings test case helpers
testCaseHoistPolymorphicLetBindings :: TTerm HoistPolymorphicLetBindingsTestCase -> TTerm TestCase
testCaseHoistPolymorphicLetBindings = inject _TestCase _TestCase_hoistPolymorphicLetBindings
hoistPolymorphicLetBindingsTestCase :: TTerm Let -> TTerm Let -> TTerm HoistPolymorphicLetBindingsTestCase
hoistPolymorphicLetBindingsTestCase input output = Phantoms.record _HoistPolymorphicLetBindingsTestCase [
_HoistPolymorphicLetBindingsTestCase_input>>: input,
_HoistPolymorphicLetBindingsTestCase_output>>: output]
-- | Convenience function for creating hoist polymorphic let bindings test cases
hoistPolymorphicLetBindingsCase :: String -> TTerm Let -> TTerm Let -> TTerm TestCaseWithMetadata
hoistPolymorphicLetBindingsCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseHoistPolymorphicLetBindings $ hoistPolymorphicLetBindingsTestCase input output)
nothing noTags
----------------------------------------
-- Type substitution test case helpers
testCaseSubstInType :: TTerm SubstInTypeTestCase -> TTerm TestCase
testCaseSubstInType = inject _TestCase _TestCase_substInType
substInTypeTestCase :: TTerm [(Name, Type)] -> TTerm Type -> TTerm Type -> TTerm SubstInTypeTestCase
substInTypeTestCase subst input output = Phantoms.record _SubstInTypeTestCase [
_SubstInTypeTestCase_substitution>>: subst,
_SubstInTypeTestCase_input>>: input,
_SubstInTypeTestCase_output>>: output]
-- | Convenience function for creating type substitution test cases
substInTypeCase :: String -> TTerm [(Name, Type)] -> TTerm Type -> TTerm Type -> TTerm TestCaseWithMetadata
substInTypeCase cname subst input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseSubstInType $ substInTypeTestCase subst input output)
nothing noTags
----------------------------------------
-- Variable occurs in type test case helpers
testCaseVariableOccursInType :: TTerm VariableOccursInTypeTestCase -> TTerm TestCase
testCaseVariableOccursInType = inject _TestCase _TestCase_variableOccursInType
variableOccursInTypeTestCase :: TTerm Name -> TTerm Type -> TTerm Bool -> TTerm VariableOccursInTypeTestCase
variableOccursInTypeTestCase variable typ expected = Phantoms.record _VariableOccursInTypeTestCase [
_VariableOccursInTypeTestCase_variable>>: variable,
_VariableOccursInTypeTestCase_type>>: typ,
_VariableOccursInTypeTestCase_expected>>: expected]
-- | Convenience function for creating variable occurs in type test cases
variableOccursCase :: String -> TTerm Name -> TTerm Type -> TTerm Bool -> TTerm TestCaseWithMetadata
variableOccursCase cname variable typ expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseVariableOccursInType $ variableOccursInTypeTestCase variable typ expected)
nothing noTags
----------------------------------------
-- Unify types test case helpers
testCaseUnifyTypes :: TTerm UnifyTypesTestCase -> TTerm TestCase
testCaseUnifyTypes = inject _TestCase _TestCase_unifyTypes
unifyTypesTestCase :: TTerm [Name] -> TTerm Type -> TTerm Type -> TTerm (Either String TypeSubst) -> TTerm UnifyTypesTestCase
unifyTypesTestCase schemaTypes left right expected = Phantoms.record _UnifyTypesTestCase [
_UnifyTypesTestCase_schemaTypes>>: schemaTypes,
_UnifyTypesTestCase_left>>: left,
_UnifyTypesTestCase_right>>: right,
_UnifyTypesTestCase_expected>>: expected]
-- | Convenience function for creating unify types test cases (expecting success)
-- The substitution is provided as a list of (name, type) pairs
unifyTypesCase :: String -> TTerm [Name] -> TTerm Type -> TTerm Type -> [(TTerm Name, TTerm Type)] -> TTerm TestCaseWithMetadata
unifyTypesCase cname schemaTypes left right substPairs = testCaseWithMetadata (Phantoms.string cname)
(testCaseUnifyTypes $ unifyTypesTestCase schemaTypes left right (Phantoms.right (Phantoms.wrap _TypeSubst (Phantoms.map (M.fromList substPairs)))))
nothing noTags
-- | Convenience function for creating unify types test cases (expecting failure)
unifyTypesFailCase :: String -> TTerm [Name] -> TTerm Type -> TTerm Type -> String -> TTerm TestCaseWithMetadata
unifyTypesFailCase cname schemaTypes left right errSubstring = testCaseWithMetadata (Phantoms.string cname)
(testCaseUnifyTypes $ unifyTypesTestCase schemaTypes left right (Phantoms.left (Phantoms.string errSubstring)))
nothing noTags
----------------------------------------
-- Join types test case helpers
testCaseJoinTypes :: TTerm JoinTypesTestCase -> TTerm TestCase
testCaseJoinTypes = inject _TestCase _TestCase_joinTypes
joinTypesTestCase :: TTerm Type -> TTerm Type -> TTerm (Either () [TypeConstraint]) -> TTerm JoinTypesTestCase
joinTypesTestCase left right expected = Phantoms.record _JoinTypesTestCase [
_JoinTypesTestCase_left>>: left,
_JoinTypesTestCase_right>>: right,
_JoinTypesTestCase_expected>>: expected]
-- | Convenience function for creating join types test cases (expecting success)
joinTypesCase :: String -> TTerm Type -> TTerm Type -> TTerm [TypeConstraint] -> TTerm TestCaseWithMetadata
joinTypesCase cname left right constraints = testCaseWithMetadata (Phantoms.string cname)
(testCaseJoinTypes $ joinTypesTestCase left right (Phantoms.right constraints))
nothing noTags
-- | Convenience function for creating join types test cases (expecting failure)
joinTypesFailCase :: String -> TTerm Type -> TTerm Type -> TTerm TestCaseWithMetadata
joinTypesFailCase cname left right = testCaseWithMetadata (Phantoms.string cname)
(testCaseJoinTypes $ joinTypesTestCase left right (Phantoms.left Phantoms.unit))
nothing noTags
----------------------------------------
-- Unshadow variables test case helpers
testCaseUnshadowVariables :: TTerm UnshadowVariablesTestCase -> TTerm TestCase
testCaseUnshadowVariables = inject _TestCase _TestCase_unshadowVariables
unshadowVariablesTestCase :: TTerm Term -> TTerm Term -> TTerm UnshadowVariablesTestCase
unshadowVariablesTestCase input output = Phantoms.record _UnshadowVariablesTestCase [
_UnshadowVariablesTestCase_input>>: input,
_UnshadowVariablesTestCase_output>>: output]
-- | Convenience function for creating unshadow variables test cases
unshadowCase :: String -> TTerm Term -> TTerm Term -> TTerm TestCaseWithMetadata
unshadowCase cname input output = testCaseWithMetadata (Phantoms.string cname)
(testCaseUnshadowVariables $ unshadowVariablesTestCase input output)
nothing noTags
-- | Inject a ValidateCoreTermTestCase into TestCase
testCaseValidateCoreTerm :: TTerm ValidateCoreTermTestCase -> TTerm TestCase
testCaseValidateCoreTerm = inject _TestCase _TestCase_validateCoreTerm
-- | Construct a ValidateCoreTermTestCase
validateCoreTermTestCase :: TTerm Bool -> TTerm Term -> TTerm (Maybe InvalidTermError) -> TTerm ValidateCoreTermTestCase
validateCoreTermTestCase typed input output = Phantoms.record _ValidateCoreTermTestCase [
_ValidateCoreTermTestCase_typed>>: typed,
_ValidateCoreTermTestCase_input>>: input,
_ValidateCoreTermTestCase_output>>: output]
-- | Convenience function for creating validation test cases
validateCoreTermCase :: String -> TTerm Bool -> TTerm Term -> TTerm (Maybe InvalidTermError) -> TTerm TestCaseWithMetadata
validateCoreTermCase cname typed input expected = testCaseWithMetadata (Phantoms.string cname)
(testCaseValidateCoreTerm $ validateCoreTermTestCase typed input expected)
nothing noTags