cleveland-0.1.1: morley-test/Test/Interpreter/Views.hs
-- SPDX-FileCopyrightText: 2021 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA
-- | Tests on on-chain views.
module Test.Interpreter.Views
( test_runtime
, test_step_constants
, test_recursion
, test_create_contract
, test_context_restore_on_exit
) where
import Fmt (Buildable, (+|), (|+))
import Test.Tasty (TestTree, testGroup)
import Morley.Tezos.Address
import Morley.Tezos.Core
import Test.Cleveland
import Test.Cleveland.Instances ()
import Test.Cleveland.Lorentz.Types
import Test.Util.Contracts
-- Tests from Tezos
--
-- Taken from https://gitlab.com/tezos/tezos/-/blob/6eef585d8e897b94b330323987ee0e6228189791/tests_python/tests_alpha/test_contract.py#L681
----------------------------------------------------------------------------
amongTezosContracts :: FilePath -> FilePath
amongTezosContracts file = contractsDir </> "tezos_examples" </> "opcodes" </> file
originateViewedContract
:: MonadCleveland caps m => m (ContractHandle Natural Natural ())
originateViewedContract =
importContract (amongTezosContracts "view_toplevel_lib.tz")
>>= \c -> originate OriginateData
{ odName = "viewedContract"
, odBalance = 777
, odStorage = 3 :: Natural
, odContract = c
}
test_runtime :: TestTree
test_runtime = testGroup "Basic interpreter logic"
[ checkContract "view_op_id" ((0, 0) :: (Natural, Natural)) (10, 3)
, checkContract "view_op_add" (42 :: Natural) 13
, checkContract "view_fib" (0 :: Natural) 55
, checkContract "view_mutual_recursion" (0 :: Natural) 20
, checkContract "view_op_nonexistent_func" True False
, checkContract "view_op_nonexistent_addr" True False
, checkContract "view_op_toplevel_inconsistent_input_type" (5 :: Natural) 0
, checkContract "view_op_toplevel_inconsistent_output_type" True False
]
where
checkContract
:: (NiceStorage st, Eq st, Buildable st, AsRPC st ~ st)
=> String -> st -> st -> TestTree
checkContract fileName initSt expected =
testScenario fileName $ scenario $ clarifyErrors ("For '" +| fileName |+ "'") do
viewedContract <- originateViewedContract
viewCaller
<- importContract @(Natural, Address) @_ @() (amongTezosContracts $ fileName <> ".tz")
>>= originateSimple "viewCaller" initSt
call viewCaller CallDefault (10, toAddress viewedContract)
getStorage viewCaller @@== expected
test_step_constants :: TestTree
test_step_constants =
testScenario "Step constants contract" $ scenario do
alice <- newAddress auto
viewedContract <- originateViewedContract
viewCaller
<- importContract @Address @(Maybe ((Mutez, Mutez), ((Address, Address), Address))) @()
(amongTezosContracts "view_op_test_step_contants.tz")
>>= originateSimple "viewCaller" Nothing
withSender alice do
call viewCaller CallDefault (toAddress viewedContract)
let expectedSelfAddress = toAddress viewedContract
expectedSender = toAddress viewCaller
expectedSource = alice
getStorage viewCaller @@== Just
( ( 0
, 777
)
, ( ( expectedSelfAddress
, expectedSender
)
, expectedSource
)
)
test_recursion :: TestTree
test_recursion =
testScenario "Recursive call" $ scenario do
contract
<- importContract @() @() @() (amongTezosContracts "view_rec.tz")
>>= originateSimple "contract" ()
call contract CallDefault ()
& expectTransferFailure gasExhaustion
test_create_contract :: TestTree
test_create_contract =
testScenario "Recursive call" $ scenario do
contractCreator
<- importContract @() @(Maybe Address) @()
(amongTezosContracts "create_contract_with_view.tz")
>>= originateSimple "contractCreator" Nothing
call contractCreator CallDefault ()
contractAddr <- getStorage contractCreator >>= \case
Nothing -> failure "Unexpected outcome"
Just addr -> pure addr
constViewObserver
<- importContract @(Natural, Address) @Natural @()
(amongTezosContracts "view_op_constant.tz")
>>= originateSimple "constViewObserver" 2
call constViewObserver CallDefault (10, contractAddr)
getStorage constViewObserver @@== 10
-- In Tezos they have a lot of tests covering the fact that environment must
-- be restored on view exist (the tests were added along with a bugfix),
-- but we don't need this, we use 'ReaderT' that makes the issue hard to produce.
test_context_restore_on_exit :: TestTree
test_context_restore_on_exit =
testScenario "Context restores" $ scenario do
viewedContract <- originateViewedContract
selfAfterView
<- importContract @Address @Address @()
(amongTezosContracts "self_after_view.tz")
>>= \c -> originate OriginateData
{ odName = "selfAfterView"
, odBalance = 1500 -- transferred by the contract further
, odStorage = toAddress viewedContract
, odContract = c
}
call selfAfterView CallDefault (toAddress viewedContract)
getStorage selfAfterView @@== toAddress selfAfterView