Revision ba5b8be64d2c68cddeeab923dcdf88c71959107b authored by Mehdi Bouaziz on 31 October 2022, 18:10:35 UTC, committed by Mehdi Bouaziz on 07 November 2022, 15:44:37 UTC
1 parent 3eccab6
Raw File
test_contract_macros.py
from os import path
import pytest
from tools.utils import (
    assert_run_script_failwith,
    assert_transfer_failwith,
    init_with_transfer,
    bake,
    assert_storage_contains,
)
from tools.client_regression import ClientRegression
from client.client import Client
from .contract_paths import MACROS_CONTRACT_PATH, CONTRACT_PATH, all_contracts


@pytest.mark.contract
class TestContractMacros:
    """Tests for contracts using macros that do not require origination."""

    @pytest.mark.parametrize(
        "contract,param,storage,expected",
        [  # FORMAT: assert_output contract_file storage input expected_result
            # Build list
            ('build_list.tz', '{}', '0', '{ 0 }'),
            ('build_list.tz', '{}', '3', '{ 0 ; 1 ; 2 ; 3 }'),
            (
                'build_list.tz',
                '{}',
                '10',
                '{ 0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9 ; 10 }',
            ),
            # Find maximum int in list -- returns None if not found
            ('max_in_list.tz', 'None', '{}', 'None'),
            ('max_in_list.tz', 'None', '{ 1 }', '(Some 1)'),
            ('max_in_list.tz', 'None', '{ -1 }', '(Some -1)'),
            (
                'max_in_list.tz',
                'None',
                '{ 10 ; -1 ; -20 ; 100 ; 0 }',
                '(Some 100)',
            ),
            (
                'max_in_list.tz',
                'None',
                '{ 10 ; -1 ; -20 ; 100 ; 0 }',
                '(Some 100)',
            ),
            (
                'max_in_list.tz',
                'None',
                '{ -10 ; -1 ; -20 ; -100 }',
                '(Some -1)',
            ),
            # Test comparisons on tez { EQ ; GT ; LT ; GE ; LE }
            (
                'compare.tz',
                '{}',
                '(Pair 1000000 2000000)',
                '{ False ; False ; True ; False ; True }',
            ),
            (
                'compare.tz',
                '{}',
                '(Pair 2000000 1000000)',
                '{ False ; True ; False ; True ; False }',
            ),
            (
                'compare.tz',
                '{}',
                '(Pair 2370000 2370000)',
                '{ True ; False ; False ; True ; True }',
            ),
            # Test ASSERT
            ('assert.tz', 'Unit', 'True', 'Unit'),
            # ASSERT_{OP}
            ('assert_eq.tz', 'Unit', '(Pair -1 -1)', 'Unit'),
            ('assert_eq.tz', 'Unit', '(Pair -1 -1)', 'Unit'),
            ('assert_neq.tz', 'Unit', '(Pair 0 -1)', 'Unit'),
            ('assert_lt.tz', 'Unit', '(Pair -1 0)', 'Unit'),
            ('assert_le.tz', 'Unit', '(Pair 0 0)', 'Unit'),
            ('assert_le.tz', 'Unit', '(Pair -1 0)', 'Unit'),
            ('assert_gt.tz', 'Unit', '(Pair 0 -1)', 'Unit'),
            ('assert_ge.tz', 'Unit', '(Pair 0 0)', 'Unit'),
            ('assert_ge.tz', 'Unit', '(Pair 0 -1)', 'Unit'),
            # ASSERT_CMP{OP}
            ('assert_cmpeq.tz', 'Unit', '(Pair -1 -1)', 'Unit'),
            ('assert_cmpneq.tz', 'Unit', '(Pair 0 -1)', 'Unit'),
            ('assert_cmplt.tz', 'Unit', '(Pair -1 0)', 'Unit'),
            ('assert_cmple.tz', 'Unit', '(Pair -1 0)', 'Unit'),
            ('assert_cmple.tz', 'Unit', '(Pair 0 0)', 'Unit'),
            ('assert_cmpgt.tz', 'Unit', '(Pair 0 -1)', 'Unit'),
            ('assert_cmpge.tz', 'Unit', '(Pair 0 -1)', 'Unit'),
            ('assert_cmpge.tz', 'Unit', '(Pair 0 0)', 'Unit'),
            # Tests the SET_CAR and SET_CDR instructions
            (
                'set_caddaadr.tz',
                '(Pair (Pair 1 2 (Pair (Pair 3 0) 4) 5) 6)',
                '3000000',
                '(Pair (Pair 1 2 (Pair (Pair 3 3000000) 4) 5) 6)',
            ),
            (
                'map_caddaadr.tz',
                '(Pair (Pair 1 2 (Pair (Pair 3 0) 4) 5) 6)',
                'Unit',
                '(Pair (Pair 1 2 (Pair (Pair 3 1000000) 4) 5) 6)',
            ),
            # Test comparisons on bytes { EQ ; GT ; LT ; GE ; LE }
            (
                'compare_bytes.tz',
                '{}',
                '(Pair 0x33 0x34)',
                '{ False ; False ; True ; False ; True }',
            ),
            (
                'compare_bytes.tz',
                '{}',
                '(Pair 0x33 0x33aa)',
                '{ False ; False ; True ; False ; True }',
            ),
            (
                'compare_bytes.tz',
                '{}',
                '(Pair 0x33 0x33)',
                '{ True ; False ; False ; True ; True }',
            ),
            (
                'compare_bytes.tz',
                '{}',
                '(Pair 0x34 0x33)',
                '{ False ; True ; False ; True ; False }',
            ),
        ],
    )
    def test_contract_input_output(
        self,
        client: Client,
        contract: str,
        param: str,
        storage: str,
        expected: str,
    ):
        assert contract.endswith(
            '.tz'
        ), "test contract should have .tz extension"
        contract = path.join(MACROS_CONTRACT_PATH, contract)
        run_script_res = client.run_script(contract, param, storage)
        assert run_script_res.storage == expected

    @pytest.mark.parametrize(
        "contract,param,storage",
        [  # FORMAT: assert_output contract_file storage input expected_result
            ('assert.tz', 'Unit', 'False'),
            ('assert_eq.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_eq.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_neq.tz', 'Unit', '(Pair -1 -1)'),
            ('assert_lt.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_lt.tz', 'Unit', '(Pair 0 0)'),
            ('assert_le.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_gt.tz', 'Unit', '(Pair -1 0)'),
            ('assert_gt.tz', 'Unit', '(Pair 0 0)'),
            ('assert_ge.tz', 'Unit', '(Pair -1 0)'),
            ('assert_cmpeq.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_cmpneq.tz', 'Unit', '(Pair -1 -1)'),
            ('assert_cmplt.tz', 'Unit', '(Pair 0 0)'),
            ('assert_cmplt.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_cmple.tz', 'Unit', '(Pair 0 -1)'),
            ('assert_cmpgt.tz', 'Unit', '(Pair 0 0)'),
            ('assert_cmpgt.tz', 'Unit', '(Pair -1 0)'),
            ('assert_cmpge.tz', 'Unit', '(Pair -1 0)'),
        ],
    )
    def test_contract_failures(self, client: Client, contract, param, storage):
        contract = path.join(MACROS_CONTRACT_PATH, contract)
        assert_run_script_failwith(client, contract, param, storage)


@pytest.mark.slow
@pytest.mark.contract
class TestGuestBook:
    """Test on the guestbook contract."""

    def test_guestbook(self, client: Client):
        contract = path.join(MACROS_CONTRACT_PATH, 'guestbook.tz')

        init_with_transfer(
            client,
            contract,
            '{ Elt "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" None }',
            100,
            'bootstrap1',
        )

        assert_transfer_failwith(
            client,
            0,
            'bootstrap2',
            'guestbook',
            ['--arg', '"Pas moi"', '--burn-cap', '10'],
        )

        client.transfer(
            0,
            'bootstrap1',
            'guestbook',
            ['-arg', '"Coucou"', '--burn-cap', '10'],
        )
        bake(client)
        assert_storage_contains(
            client,
            'guestbook',
            '{ Elt "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" (Some "Coucou") }',
        )

        assert_transfer_failwith(
            client,
            0,
            'bootstrap3',
            'guestbook',
            ['--arg', '"Pas moi non plus"', '--burn-cap', '10'],
        )
        assert_transfer_failwith(
            client,
            0,
            'bootstrap1',
            'guestbook',
            ['--arg', '"Recoucou ?"', '--burn-cap', '10'],
        )


@pytest.mark.slow
@pytest.mark.contract
class TestBigmap:
    """Tests on the big_map_mem contract."""

    def test_bigmap(self, client: Client):
        contract = path.join(MACROS_CONTRACT_PATH, 'big_map_mem.tz')

        init_with_transfer(
            client,
            contract,
            '(Pair { Elt 1 Unit ; Elt 2 Unit ; Elt 3 Unit } Unit)',
            100,
            'bootstrap1',
        )

        client.transfer(
            1,
            'bootstrap1',
            'big_map_mem',
            ['-arg', '(Pair 0 False)', '--burn-cap', '10'],
        )
        bake(client)

        assert_transfer_failwith(
            client,
            0,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 0 True)', '--burn-cap', '10'],
        )

        client.transfer(
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 0 False)', '--burn-cap', '10'],
        )
        bake(client)
        assert_transfer_failwith(
            client,
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 0 True)', '--burn-cap', '10'],
        )
        client.transfer(
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 1 True)', '--burn-cap', '10'],
        )
        bake(client)
        assert_transfer_failwith(
            client,
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 1 False)', '--burn-cap', '10'],
        )
        client.transfer(
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 2 True)', '--burn-cap', '10'],
        )
        bake(client)
        assert_transfer_failwith(
            client,
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 2 False)', '--burn-cap', '10'],
        )
        client.transfer(
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 3 True)', '--burn-cap', '10'],
        )
        bake(client)
        assert_transfer_failwith(
            client,
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 3 False)', '--burn-cap', '10'],
        )
        client.transfer(
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 4 False)', '--burn-cap', '10'],
        )
        bake(client)
        assert_transfer_failwith(
            client,
            1,
            'bootstrap1',
            'big_map_mem',
            ['--arg', '(Pair 4 True)', '--burn-cap', '10'],
        )


@pytest.mark.slow
@pytest.mark.contract
class TestBigmapGetAdd:
    """Tests on the big_map_get_add contract."""

    def test_bigmap(self, client: Client):
        contract = path.join(MACROS_CONTRACT_PATH, 'big_map_get_add.tz')

        init_with_transfer(
            client,
            contract,
            '(Pair { Elt 0 1 ; Elt 1 2 ; Elt 2 3 } Unit)',
            100,
            'bootstrap1',
        )

        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 200 (Some 2)) (Pair 200 (Some 2)))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)
        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 200 None) (Pair 200 None))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)
        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 200 None) (Pair 300 None))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)
        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 1 None) (Pair 200 None))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)
        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 1 (Some 2)) (Pair 0 (Some 1)))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)
        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 400 (Some 1232)) (Pair 400 (Some 1232)))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)
        client.transfer(
            1,
            'bootstrap1',
            'big_map_get_add',
            [
                '--arg',
                '(Pair (Pair 401 (Some 0)) (Pair 400 (Some 1232)))',
                '--burn-cap',
                '10',
            ],
        )
        bake(client)


@pytest.mark.regression
class TestMacroExpansion:
    """Test expanding macros"""

    @pytest.mark.parametrize("contract", all_contracts(['macros']))
    def test_macro_expansion(
        self, client_regtest: ClientRegression, contract: str
    ):
        """This test expands macros in all macro test contracts, with
        regression detection enabled. This test should fail if the definition
        of any macros change.
        """
        client_regtest.expand_macros(path.join(CONTRACT_PATH, contract))
back to top