From d43ea7785eaa3547d17b391d7f973d558f4122a0 Mon Sep 17 00:00:00 2001 From: antazoey Date: Mon, 21 Oct 2024 16:24:37 -0500 Subject: [PATCH] test: use `ape test` to test ape (#2327) --- .github/workflows/test.yaml | 8 +- pyproject.toml | 1 - tests/conftest.py | 107 +++++------------- tests/functional/conftest.py | 4 +- tests/functional/geth/test_contract.py | 4 +- tests/functional/test_accounts.py | 90 +++++++-------- tests/functional/test_cli.py | 31 ++--- tests/functional/test_contract_event.py | 8 +- .../test_default_sender_context_manager.py | 45 ++++---- tests/functional/test_provider.py | 4 +- tests/integration/cli/test_accounts.py | 4 +- tests/integration/cli/test_console.py | 41 ++++--- tests/integration/cli/test_networks.py | 2 +- 13 files changed, 147 insertions(+), 202 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4128112885..236f005ecd 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -95,13 +95,13 @@ jobs: pip install .[test] - name: Run Functional Tests - run: pytest tests/functional -m "not fuzzing" -s --cov=src --cov-append -n auto --dist loadgroup + run: ape test tests/functional -m "not fuzzing" -s --cov=src --cov-append -n auto --dist loadgroup - name: Run Integration Tests - run: pytest tests/integration -m "not fuzzing" -s --cov=src --cov-append -n auto --dist loadgroup + run: ape test tests/integration -m "not fuzzing" -s --cov=src --cov-append -n auto --dist loadgroup - name: Run Performance Tests - run: pytest tests/performance -s + run: ape test tests/performance -s fuzzing: runs-on: ubuntu-latest @@ -123,4 +123,4 @@ jobs: pip install .[test] - name: Run Tests - run: pytest -m "fuzzing" --no-cov -s + run: ape test -m "fuzzing" --no-cov -s diff --git a/pyproject.toml b/pyproject.toml index 338e5675f4..46ced0756d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,6 @@ norecursedirs = "projects" # NOTE: 'no:ape_test' Prevents the ape plugin from activating on our tests # And 'pytest_ethereum' is not used and causes issues in some environments. addopts = """ --p no:ape_test -p no:pytest_ethereum """ diff --git a/tests/conftest.py b/tests/conftest.py index 9c02bad3cd..24f3fcba32 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,6 @@ import ape from ape.contracts import ContractContainer -from ape.exceptions import APINotImplementedError, ProviderNotConnectedError, UnknownSnapshotError from ape.logging import LogLevel, logger from ape.managers.project import Project from ape.pytest.config import ConfigWrapper @@ -91,7 +90,7 @@ def validate_cwd(start_dir): @pytest.fixture -def project(): +def example_project(): path = "tests/functional/data/contracts/ethereum/local" with ape.project.temp_config(contracts_folder=path): ape.project.clean() @@ -135,7 +134,8 @@ def plugin_manager(): @pytest.fixture(scope="session") -def accounts(): +def account_manager(): + # NOTE: `accounts` fixture comes with ape_test as the test-accounts. return ape.accounts @@ -145,43 +145,28 @@ def compilers(): @pytest.fixture(scope="session") -def networks(): - return ape.networks +def owner(accounts): + return accounts[0] @pytest.fixture(scope="session") -def chain(): - return ape.chain +def sender(accounts): + return accounts[1] @pytest.fixture(scope="session") -def test_accounts(accounts): - return accounts.test_accounts +def receiver(accounts): + return accounts[2] @pytest.fixture(scope="session") -def owner(test_accounts): - return test_accounts[0] +def not_owner(accounts): + return accounts[3] @pytest.fixture(scope="session") -def sender(test_accounts): - return test_accounts[1] - - -@pytest.fixture(scope="session") -def receiver(test_accounts): - return test_accounts[2] - - -@pytest.fixture(scope="session") -def not_owner(test_accounts): - return test_accounts[3] - - -@pytest.fixture(scope="session") -def helper(test_accounts): - return test_accounts[4] +def helper(accounts): + return accounts[4] @pytest.fixture(scope="session") @@ -190,18 +175,18 @@ def mystruct_c(): @pytest.fixture -def signer(test_accounts): - return test_accounts[5] +def signer(accounts): + return accounts[5] @pytest.fixture -def geth_account(test_accounts): - return test_accounts[6] +def geth_account(accounts): + return accounts[6] @pytest.fixture -def geth_second_account(test_accounts): - return test_accounts[7] +def geth_second_account(accounts): + return accounts[7] @pytest.fixture(scope="session") @@ -289,44 +274,6 @@ def geth_provider(networks): yield networks.provider -@contextmanager -def _isolation(): - if ape.networks.active_provider is None: - raise AssertionError("Isolation should only be used with a connected provider.") - - init_network_name = ape.chain.provider.network.name - init_provider_name = ape.chain.provider.name - - try: - snapshot = ape.chain.snapshot() - except (APINotImplementedError, ProviderNotConnectedError): - # Provider not used or connected in test. - snapshot = None - - yield - - if ( - snapshot is None - or ape.networks.active_provider is None - or ape.chain.provider.network.name != init_network_name - or ape.chain.provider.name != init_provider_name - ): - return - - try: - ape.chain.restore(snapshot) - except (UnknownSnapshotError, ProviderNotConnectedError): - # Assume snapshot removed for testing reasons - # or the provider was not needed to be connected for the test. - pass - - -@pytest.fixture(autouse=True) -def eth_tester_isolation(eth_tester_provider): - with _isolation(): - yield - - @pytest.fixture def empty_data_folder(): # Avoid user's global ape-config data. @@ -527,11 +474,17 @@ def __init__( self.root_cmd = root_cmd or [] self.data_folder = data_folder - def invoke(self, *subcommand: str, input=None, timeout: int = 40): + def invoke( + self, + *subcommand: str, + input=None, + timeout: int = 40, + env: Optional[dict] = None, + ): subcommand = subcommand or () cmd_ls = [*self.root_cmd, *subcommand] - env = dict(os.environ) + env = {**dict(os.environ), **(env or {})} if self.data_folder: env["APE_DATA_FOLDER"] = str(self.data_folder) @@ -562,7 +515,7 @@ def __init__( super().__init__([str(ape_path), *root], data_folder=data_folder) self.project = None - def invoke(self, *subcommand: str, input=None, timeout: int = 40): + def invoke(self, *subcommand: str, input=None, timeout: int = 40, env: Optional[dict] = None): if self.project: try: here = os.getcwd() @@ -574,7 +527,7 @@ def invoke(self, *subcommand: str, input=None, timeout: int = 40): else: here = None - result = super().invoke(*subcommand, input=input, timeout=timeout) + result = super().invoke(*subcommand, input=input, timeout=timeout, env=env) if here: os.chdir(here) @@ -591,7 +544,7 @@ def exit_code(self) -> int: @property def output(self) -> str: - return self._completed_process.stdout + return self._completed_process.stdout or self._completed_process.stderr CUSTOM_NETWORK_0 = "apenet" diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py index 05add6558b..580bdc807a 100644 --- a/tests/functional/conftest.py +++ b/tests/functional/conftest.py @@ -610,9 +610,9 @@ def struct_input_for_call(owner): @pytest.fixture(scope="session") -def output_from_struct_input_call(test_accounts): +def output_from_struct_input_call(accounts): # Expected when using `struct_input_for_call`. - addr = test_accounts[0].address.replace("0x", "") + addr = accounts[0].address.replace("0x", "") return HexBytes( f"0x26e0a196000000000000000000000000{addr}000000000000000000000000000000000" f"0000000000000000000000000000080000000000000000000000000000000000000000000" diff --git a/tests/functional/geth/test_contract.py b/tests/functional/geth/test_contract.py index b40cb53b43..0c4d6fba25 100644 --- a/tests/functional/geth/test_contract.py +++ b/tests/functional/geth/test_contract.py @@ -107,8 +107,8 @@ def test_revert_out_of_gas_error_allow(geth_account, geth_second_account, geth_p @geth_process_test -def test_revert_allow(test_accounts, geth_contract): - not_owner = test_accounts[0] +def test_revert_allow(accounts, geth_contract): + not_owner = accounts[0] # 'sender' is not the owner so it will revert (with a message) receipt = geth_contract.setNumber(100199, sender=not_owner, raise_on_revert=False) diff --git a/tests/functional/test_accounts.py b/tests/functional/test_accounts.py index b1db310813..e7a0a50534 100644 --- a/tests/functional/test_accounts.py +++ b/tests/functional/test_accounts.py @@ -20,7 +20,6 @@ ) from ape.types import AutoGasLimit from ape.types.signatures import recover_signer -from ape.utils.testing import DEFAULT_NUMBER_OF_TEST_ACCOUNTS from ape_accounts import ( KeyfileAccount, generate_account, @@ -362,7 +361,7 @@ def test_send_transaction_without_enough_funds_impersonated_account( ): address = "0x4838B106FCe9647Bdf1E7877BF73cE8B0BAD5f97" # Not a test account! impersonated_account = ImpersonatedAccount(raw_address=address) - accounts.test_accounts._impersonated_accounts[address] = impersonated_account + accounts._impersonated_accounts[address] = impersonated_account # Basically, it failed anywhere else besides the AccountsError you get from not # enough balance. @@ -376,23 +375,21 @@ def test_send_transaction_sets_defaults(sender, receiver): assert receipt.required_confirmations == 0 -def test_accounts_splice_access(test_accounts): - a, b = test_accounts[:2] - assert a == test_accounts[0] - assert b == test_accounts[1] - c = test_accounts[-1] - assert c == test_accounts[len(test_accounts) - 1] - expected = ( - (len(test_accounts) // 2) if len(test_accounts) % 2 == 0 else (len(test_accounts) // 2 + 1) - ) - assert len(test_accounts[::2]) == expected +def test_accounts_splice_access(accounts): + a, b = accounts[:2] + assert a == accounts[0] + assert b == accounts[1] + c = accounts[-1] + assert c == accounts[len(accounts) - 1] + expected = (len(accounts) // 2) if len(accounts) % 2 == 0 else (len(accounts) // 2 + 1) + assert len(accounts[::2]) == expected def test_accounts_address_access(owner, accounts): assert accounts[owner.address] == owner -def test_accounts_address_access_conversion_fail(accounts): +def test_accounts_address_access_conversion_fail(account_manager): with pytest.raises( KeyError, match=( @@ -400,7 +397,7 @@ def test_accounts_address_access_conversion_fail(accounts): r"Do you have the necessary conversion plugins installed?" ), ): - _ = accounts["FAILS"] + _ = account_manager["FAILS"] def test_accounts_address_access_not_found(accounts): @@ -409,15 +406,15 @@ def test_accounts_address_access_not_found(accounts): _ = accounts[address] -def test_test_accounts_address_access_conversion_fail(test_accounts): +def test_test_accounts_address_access_conversion_fail(accounts): with pytest.raises(KeyError, match=r"No account with ID 'FAILS'"): - _ = test_accounts["FAILS"] + _ = accounts["FAILS"] -def test_test_accounts_address_access_not_found(test_accounts): +def test_test_accounts_address_access_not_found(accounts): address = "0x1222262222222922222222222222222222222222" with pytest.raises(KeyError, match=rf"No account with address '{address}'\."): - _ = test_accounts[address] + _ = accounts[address] def test_accounts_contains(accounts, owner): @@ -459,9 +456,9 @@ def test_impersonated_account_ignores_signature_check_on_txn(accounts, address): account = ImpersonatedAccount(raw_address=address) # Impersonate hack, since no providers in core actually support it. - accounts.test_accounts._impersonated_accounts[address] = account - other_0 = accounts.test_accounts[8] - other_1 = accounts.test_accounts[9] + accounts._impersonated_accounts[address] = account + other_0 = accounts[8] + other_1 = accounts[9] txn = other_0.transfer(other_1, "1 gwei").transaction # Hack in fake sender. @@ -553,13 +550,13 @@ def test_unlock_with_wrong_passphrase_from_env(keyfile_account): assert keyfile_account.locked -def test_unlock_and_reload(runner, accounts, keyfile_account, message): +def test_unlock_and_reload(runner, account_manager, keyfile_account, message): """ Tests against a condition where reloading after unlocking would not honor unlocked state. """ keyfile_account.unlock(passphrase=PASSPHRASE) - reloaded_account = accounts.load(keyfile_account.alias) + reloaded_account = account_manager.load(keyfile_account.alias) # y: yes, sign (note: unlocking makes the key available but is not the same as autosign). with runner.isolation(input="y\n"): @@ -567,23 +564,20 @@ def test_unlock_and_reload(runner, accounts, keyfile_account, message): assert keyfile_account.check_signature(message, signature) -def test_custom_num_of_test_accounts_config(test_accounts, project): - custom_number_of_test_accounts = 20 +def test_custom_num_of_test_accounts_config(accounts, project): + custom_number_of_test_accounts = 25 test_config = { "test": { "number_of_accounts": custom_number_of_test_accounts, } } - - assert len(test_accounts) == DEFAULT_NUMBER_OF_TEST_ACCOUNTS - with project.temp_config(**test_config): - assert len(test_accounts) == custom_number_of_test_accounts + assert len(accounts) == custom_number_of_test_accounts -def test_test_accounts_repr(test_accounts): - actual = repr(test_accounts) - assert all(a.address in actual for a in test_accounts) +def test_test_accounts_repr(accounts): + actual = repr(accounts) + assert all(a.address in actual for a in accounts) def test_account_comparison_to_non_account(core_account): @@ -591,14 +585,14 @@ def test_account_comparison_to_non_account(core_account): assert core_account != "foo" -def test_create_account(test_accounts): - length_at_start = len(test_accounts) - created_account = test_accounts.generate_test_account() +def test_create_account(accounts): + length_at_start = len(accounts) + created_account = accounts.generate_test_account() assert isinstance(created_account, TestAccount) assert created_account.index == length_at_start - second_created_account = test_accounts.generate_test_account() + second_created_account = accounts.generate_test_account() assert created_account.address != second_created_account.address assert second_created_account.index == created_account.index + 1 @@ -627,42 +621,42 @@ def test_is_not_contract(owner, keyfile_account): assert not keyfile_account.is_contract -def test_using_different_hd_path(test_accounts, project, eth_tester_provider): +def test_using_different_hd_path(accounts, project, eth_tester_provider): test_config = { "test": { "hd_path": "m/44'/60'/0/0", } } - old_address = test_accounts[0].address + old_address = accounts[0].address original_settings = eth_tester_provider.settings.model_dump(by_alias=True) with project.temp_config(**test_config): eth_tester_provider.update_settings(test_config["test"]) - new_address = test_accounts[0].address + new_address = accounts[0].address eth_tester_provider.update_settings(original_settings) assert old_address != new_address -def test_using_random_mnemonic(test_accounts, project, eth_tester_provider): +def test_using_random_mnemonic(accounts, project, eth_tester_provider): mnemonic = "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat" test_config = {"test": {"mnemonic": mnemonic}} - old_address = test_accounts[0].address + old_address = accounts[0].address original_settings = eth_tester_provider.settings.model_dump(by_alias=True) with project.temp_config(**test_config): eth_tester_provider.update_settings(test_config["test"]) - new_address = test_accounts[0].address + new_address = accounts[0].address eth_tester_provider.update_settings(original_settings) assert old_address != new_address -def test_iter_test_accounts(test_accounts): - test_accounts.reset() - accounts = list(iter(test_accounts)) +def test_iter_test_accounts(accounts): + accounts.reset() + accounts = list(iter(accounts)) actual = len(accounts) - expected = len(test_accounts) + expected = len(accounts) assert actual == expected @@ -908,6 +902,6 @@ def test_import_account_from_private_key_insecure_passphrase(delete_account_afte import_account_from_private_key(simple_alias, "simple", PRIVATE_KEY) -def test_load(accounts, keyfile_account): - account = accounts.load(keyfile_account.alias) +def test_load(account_manager, keyfile_account): + account = account_manager.load(keyfile_account.alias) assert account == keyfile_account diff --git a/tests/functional/test_cli.py b/tests/functional/test_cli.py index bde52e3ac5..35ea0dc489 100644 --- a/tests/functional/test_cli.py +++ b/tests/functional/test_cli.py @@ -109,21 +109,21 @@ def _teardown_numb_acct_change(accounts): @pytest.fixture -def no_accounts(accounts, empty_data_folder, project): - data = _setup_temp_acct_number_change(accounts, 0) +def no_accounts(account_manager, empty_data_folder, project): + data = _setup_temp_acct_number_change(account_manager, 0) with project.temp_config(**data): yield - _teardown_numb_acct_change(accounts) + _teardown_numb_acct_change(account_manager) @pytest.fixture -def one_account(accounts, empty_data_folder, project, test_accounts): - data = _setup_temp_acct_number_change(accounts, 1) +def one_account(account_manager, empty_data_folder, project): + data = _setup_temp_acct_number_change(account_manager, 1) with project.temp_config(**data): - yield test_accounts[0] + yield account_manager.test_accounts[0] - _teardown_numb_acct_change(accounts) + _teardown_numb_acct_change(account_manager) def get_expected_account_str(acct): @@ -371,9 +371,9 @@ def cmd(account): @pytest.mark.parametrize("test_key", ("test", "TEST")) -def test_account_option_can_use_test_account(runner, test_accounts, test_key): +def test_account_option_can_use_test_account(runner, accounts, test_key): index = 7 - test_account = test_accounts[index] + test_account = accounts[index] @click.command() @account_option() @@ -455,13 +455,14 @@ def cmd(): def test_verbosity_option_uses_logger_level_as_default(runner): - @click.command() - @verbosity_option(default=None) - def cmd(): - click.echo(f"LogLevel={logger.level}") - pass - with logger.at_level(LogLevel.DEBUG): + + @click.command() + @verbosity_option(default=None) + def cmd(): + click.echo(f"LogLevel={logger.level}") + pass + result = runner.invoke(cmd) assert "LogLevel=10" in result.output diff --git a/tests/functional/test_contract_event.py b/tests/functional/test_contract_event.py index c4c607ef37..3bd4977897 100644 --- a/tests/functional/test_contract_event.py +++ b/tests/functional/test_contract_event.py @@ -124,15 +124,15 @@ def test_contract_logs_range(chain, contract_instance, owner, assert_log_values) def test_contract_logs_range_by_address( - mocker, chain, eth_tester_provider, test_accounts, contract_instance, owner, assert_log_values + mocker, chain, eth_tester_provider, accounts, contract_instance, owner, assert_log_values ): get_logs_spy = mocker.spy(eth_tester_provider.tester.ethereum_tester, "get_logs") - contract_instance.setAddress(test_accounts[1], sender=owner) + contract_instance.setAddress(accounts[1], sender=owner) height = chain.blocks.height logs = [ log for log in contract_instance.AddressChange.range( - height, height + 1, search_topics={"newAddress": test_accounts[1]} + height, height + 1, search_topics={"newAddress": accounts[1]} ) ] @@ -151,7 +151,7 @@ def test_contract_logs_range_by_address( ], } assert actual == expected - assert logs == [contract_instance.AddressChange(newAddress=test_accounts[1])] + assert logs == [contract_instance.AddressChange(newAddress=accounts[1])] def test_contracts_log_multiple_addresses( diff --git a/tests/functional/test_default_sender_context_manager.py b/tests/functional/test_default_sender_context_manager.py index e908f8c8da..c6bff8059e 100644 --- a/tests/functional/test_default_sender_context_manager.py +++ b/tests/functional/test_default_sender_context_manager.py @@ -4,18 +4,18 @@ from ape.pytest.contextmanagers import RevertsContextManager as reverts -def test_default_sender_test_account(solidity_contract_instance, owner, test_accounts): - with test_accounts.use_sender(owner): +def test_default_sender_test_account(solidity_contract_instance, owner, accounts): + with accounts.use_sender(owner): tx = solidity_contract_instance.setNumber(1) assert tx.transaction.sender == owner.address with pytest.raises(SignatureError): solidity_contract_instance.setNumber(2) - with test_accounts.use_sender(owner.address): + with accounts.use_sender(owner.address): tx = solidity_contract_instance.setNumber(1) assert tx.transaction.sender == owner.address - with test_accounts.use_sender(owner.index): + with accounts.use_sender(owner.index): tx = solidity_contract_instance.setNumber(1) assert tx.transaction.sender == owner.address @@ -23,55 +23,56 @@ def test_default_sender_test_account(solidity_contract_instance, owner, test_acc def test_default_sender_account( solidity_contract_container, networks_connected_to_tester, - accounts, + account_manager, keyfile_account, ): - owner = accounts[0] passphrase = "asdf1234" - with accounts.use_sender(owner) as acct: + with account_manager.use_sender(keyfile_account) as acct: acct.set_autosign(True, passphrase) - contract = owner.deploy(solidity_contract_container, 0) + contract = keyfile_account.deploy(solidity_contract_container, 0) - with accounts.use_sender(owner) as acct: + with account_manager.use_sender(keyfile_account) as acct: acct.set_autosign(True, passphrase) tx = contract.setNumber(1) - assert tx.transaction.sender == owner.address + assert tx.transaction.sender == keyfile_account.address with pytest.raises(SignatureError): contract.setNumber(2) - with accounts.use_sender(owner.address) as acct: + with account_manager.use_sender(keyfile_account.address) as acct: acct.set_autosign(True, passphrase) tx = contract.setNumber(1) - assert tx.transaction.sender == owner.address + assert tx.transaction.sender == keyfile_account.address - with accounts.use_sender(owner.alias) as acct: + with account_manager.use_sender(keyfile_account.alias) as acct: acct.set_autosign(True, passphrase) tx = contract.setNumber(1) - assert tx.transaction.sender == owner.address + assert tx.transaction.sender == keyfile_account.address - with accounts.use_sender(0) as acct: + with account_manager.use_sender(0) as acct: acct.set_autosign(True, passphrase) tx = contract.setNumber(1) - assert tx.transaction.sender == owner.address + assert tx.transaction.sender == keyfile_account.address -def test_nested_default_sender(solidity_contract_instance, owner, test_accounts, not_owner): - with test_accounts.use_sender(owner): +def test_nested_default_sender(solidity_contract_instance, owner, accounts, not_owner): + with accounts.use_sender(owner): tx = solidity_contract_instance.setNumber(1) assert tx.transaction.sender == owner.address - with test_accounts.use_sender(not_owner): + with accounts.use_sender(not_owner): with reverts(): solidity_contract_instance.setNumber(2) + solidity_contract_instance.setNumber(3) assert tx.transaction.sender == owner.address -def test_with_error(solidity_contract_instance, accounts, not_owner): +def test_with_error(solidity_contract_instance, account_manager, not_owner): # safe to use reverts with use_sender and when outside of the use_sender # there is no remaining default_user set with reverts("!authorized"): - with accounts.test_accounts.use_sender(not_owner): + with account_manager.test_accounts.use_sender(not_owner): solidity_contract_instance.setNumber(2) - assert accounts.default_sender is None + + assert account_manager.default_sender is None diff --git a/tests/functional/test_provider.py b/tests/functional/test_provider.py index 97b15c58ab..9b8fc8de04 100644 --- a/tests/functional/test_provider.py +++ b/tests/functional/test_provider.py @@ -242,11 +242,11 @@ def test_supports_tracing(eth_tester_provider): assert not eth_tester_provider.supports_tracing -def test_provider_get_balance(project, networks, accounts): +def test_get_balance(networks, accounts): """ Test that the address is an AddressType. """ - balance = networks.provider.get_balance(accounts.test_accounts[0].address) + balance = networks.provider.get_balance(accounts[0].address) assert type(balance) is int assert balance == DEFAULT_TEST_ACCOUNT_BALANCE diff --git a/tests/integration/cli/test_accounts.py b/tests/integration/cli/test_accounts.py index f0bcce9486..a0087033e3 100644 --- a/tests/integration/cli/test_accounts.py +++ b/tests/integration/cli/test_accounts.py @@ -184,7 +184,7 @@ def test_import_mnemonic_custom_hdpath( @run_once -def test_export(ape_cli, runner, temp_keyfile, keyfile_account, test_accounts): +def test_export(ape_cli, runner, temp_keyfile, keyfile_account, accounts): # export key result = runner.invoke( ape_cli, @@ -196,7 +196,7 @@ def test_export(ape_cli, runner, temp_keyfile, keyfile_account, test_accounts): assert keyfile_account.address in result.output # NOTE: Both of these accounts are the same as the first # test account. - assert test_accounts[0].private_key in result.output + assert accounts[0].private_key in result.output @run_once diff --git a/tests/integration/cli/test_console.py b/tests/integration/cli/test_console.py index 647268284b..fac1c5ec0f 100644 --- a/tests/integration/cli/test_console.py +++ b/tests/integration/cli/test_console.py @@ -1,11 +1,23 @@ +import os +import subprocess from pathlib import Path import pytest from ape import __all__ +from tests.conftest import ApeSubprocessRunner from tests.integration.cli.utils import skip_projects, skip_projects_except +@pytest.fixture +def console_runner(config): + class ConsoleSubprocessRunner(ApeSubprocessRunner): + def __init__(self): + super().__init__("console", data_folder=config.DATA_FOLDER) + + return ConsoleSubprocessRunner() + + @pytest.fixture(params=("path", "root")) def extras_base_path(integ_project, request): if request.param == "path": @@ -236,27 +248,18 @@ def test_console_bal_magic(integ_project, ape_cli, runner, keyfile_account): @skip_projects_except("with-contracts") -def test_uncaught_txn_err(integ_project, ape_cli, runner, mocker): - # For some reason, not showing in result.output, so captured another way. - handler = mocker.patch("ape_console.plugin.handle_ape_exception") +def test_uncaught_txn_err(integ_project, console_runner): cmd_ls = [ "%load_ext ape_console.plugin", "account = accounts.test_accounts[0]", "contract = account.deploy(project.ContractA)", - "receipt = contract.setNumber(5, sender=account)", - "print(receipt)", + "contract.setNumber(5, sender=account)", "exit", ] cmd_str = "\n".join(cmd_ls) - arguments = ("console", "--project", f"{integ_project.path}") - runner.invoke( - ape_cli, - arguments, - input=f"{cmd_str}\n", - catch_exceptions=False, - ) - err = handler.call_args[0][0] - assert str(err) == "Transaction failed." + console_runner.project = integ_project + result = console_runner.invoke(input=f"{cmd_str}\n") + assert "ERROR: (ContractLogicError) Transaction failed." in result.output def test_console_none_network(integ_project, ape_cli, runner): @@ -266,7 +269,7 @@ def test_console_none_network(integ_project, ape_cli, runner): @skip_projects_except("with-contracts") -def test_console_natspecs(integ_project, ape_cli, runner, solidity_contract_type): +def test_console_natspecs(integ_project, solidity_contract_type, console_runner): """ This test shows that the various natspec integrations with ABI-backed types work in ``ape console``. @@ -287,7 +290,6 @@ def test_console_natspecs(integ_project, ape_cli, runner, solidity_contract_type "exit", ] cmd_str = "\n".join(cmd_ls) - arguments = ("console", "--project", f"{integ_project.path}") expected_method = """ setNumber(uint256 num) @custom:emits Emits a `NumberChange` event with the previous number, the new number, and the previous block hash @@ -301,12 +303,7 @@ def test_console_natspecs(integ_project, ape_cli, runner, solidity_contract_type @details Emitted when number is changed. `newNum` is the new number from the call. Expected every time number changes. """.strip() # flake8: on - result = runner.invoke( - ape_cli, - arguments, - input=f"{cmd_str}\n", - catch_exceptions=False, - ) + result = console_runner.invoke("--project", f"{integ_project.path}", input=f"{cmd_str}\n") # Getting rid of newlines as terminal-breakage never consistent in tests. actual = result.output.replace("\n", "") diff --git a/tests/integration/cli/test_networks.py b/tests/integration/cli/test_networks.py index b09b8187c1..b9578dd6e2 100644 --- a/tests/integration/cli/test_networks.py +++ b/tests/integration/cli/test_networks.py @@ -153,7 +153,7 @@ def test_list_geth(ape_cli, runner, networks, project): @run_once -def test_list_filter_networks(ape_cli, runner, networks): +def test_list_filter_networks(ape_cli, runner): result = runner.invoke(ape_cli, ("networks", "list", "--network", "sepolia")) assert result.exit_code == 0