-- SPDX-FileCopyrightText: 2020 Tocqueville Group -- -- SPDX-License-Identifier: LicenseRef-MIT-TQ module Test.Lambda ( test_Lambdas , sumLambdaCalledOnce , sumLambdaCalledTwice , lambdasSideEffects , lambdaInLambda1 , lambdaInLambda2 , pathSumLambdaCalledOnce , pathSumLambdaCalledTwice , pathLambdasSideEffects , pathLambdaInLambda1 , pathLambdaInLambda2 ) where import Prelude import Hedgehog (Gen) import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range import Test.Hspec.Expectations (errorCall, shouldThrow) import Test.Tasty (TestTree) import Test.Tasty.HUnit (testCase) import Hedgehog.Gen.Tezos.Crypto (genKeyHash) import Lorentz hiding (map) import Michelson.Interpret (MichelsonFailed(..)) import Michelson.Runtime.GState import qualified Michelson.Typed as T import Test.Code.Lambda import Test.Util test_Lambdas :: [TestTree] test_Lambdas = [ testIndigoContract "Pure lambda called once" genIntegerList genInteger (validateContractSt sumLambdaCheck) sumLambdaCalledOnce pathSumLambdaCalledOnce , testIndigoContract "Pure lambda called twice" genIntegerList genInteger (validateContractSt sumLambdaCheck) sumLambdaCalledTwice pathSumLambdaCalledTwice , testIndigoContract "Lambda with side effects" (Gen.maybe genKeyHash) genInteger (validateContract lambdasSideEffectsCheck) lambdasSideEffects pathLambdasSideEffects , testIndigoContract "Inner lambdas" genSmallMatrix genInteger (validateContractSt lambdaInLambdaCheck) lambdaInLambda1 pathLambdaInLambda1 , testIndigoContract "Inner lambdas2" genSmallMatrix genInteger (validateContractSt lambdaInLambdaCheck) lambdaInLambda2 pathLambdaInLambda2 , testCase "Outer scope error" $ (pure $! lambdaOuterVarClosure) `shouldThrow` (errorCall "In a scope of function you are using a variable from an outer scope. Closures are not supported yet.") ] where genInteger = Gen.integral (Range.linearFrom 0 -1000 1000) genIntegerList = Gen.list (Range.linear 0 100) genInteger pathSumLambdaCalledOnce :: FilePath pathSumLambdaCalledOnce = "test/contracts/golden/lambda/pure_lambda_called_once.tz" pathSumLambdaCalledTwice :: FilePath pathSumLambdaCalledTwice = "test/contracts/golden/lambda/pure_lambda_called_twice.tz" pathLambdasSideEffects :: FilePath pathLambdasSideEffects = "test/contracts/golden/lambda/lambda_side_effects.tz" pathLambdaInLambda1 :: FilePath pathLambdaInLambda1 = "test/contracts/golden/lambda/impure_inner_lambdas.tz" pathLambdaInLambda2 :: FilePath pathLambdaInLambda2 = "test/contracts/golden/lambda/impure_inner_lambdas2.tz" sumLambdaCheck :: [Integer] -> Integer -> Either MichelsonFailed Integer sumLambdaCheck param _st = Right $ sum param lambdasSideEffectsCheck :: Maybe KeyHash -> Integer -> Either MichelsonFailed ([Operation], Integer) lambdasSideEffectsCheck param st = Right ([crConOp 1, crConOp 0], st + 2) where crConOp c = T.OpCreateContract $ T.CreateContract genesisAddress param (toMutez 0) (T.VInt c) (T.cCode $ compileLorentzContract dummyContract) genSmallMatrix :: Gen SmallMatrix genSmallMatrix = fmap SmallMatrix $ Gen.list (Range.linear 0 15) $ Gen.list (Range.linear 0 15) $ Gen.integral (Range.linearFrom 0 -1000 1000) lambdaInLambdaCheck :: SmallMatrix -> Integer -> Either MichelsonFailed Integer lambdaInLambdaCheck (SmallMatrix param) st = Right $ sum (st : map sum param)