Skip to content

Commit

Permalink
feat: add --project flag to ape test command (#2403)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Dec 9, 2024
1 parent 5f2d28d commit ed45b19
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/ape/managers/project.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os
import random
import shutil
from collections.abc import Callable, Iterable, Iterator
Expand Down Expand Up @@ -2568,6 +2569,36 @@ def clean(self):
self.sources._path_cache = None
self._clear_cached_config()

def chdir(self, path: Path):
"""
Change the local project to the new path.
Args:
path (Path): The path of the new project.
"""
if self.path == path:
return # Already there!

os.chdir(path)

# Clear cached properties.
for prop in (
"path",
"_deduced_contracts_folder",
"project_api",
"contracts",
"interfaces_folder",
"sources",
):
self.__dict__.pop(prop, None)

# Re-initialize
self._session_source_change_check = set()
self._config_override = {}
self._base_path = Path(path).resolve()
self.manifest_path = self._base_path / ".build" / "__local__.json"
self._manifest = self.load_manifest()

def reload_config(self):
"""
Reload the local ape-config.yaml file.
Expand Down
4 changes: 4 additions & 0 deletions src/ape/pytest/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def add_option(*names, **kwargs):
help="A comma-separated list of contract:method-name glob-patterns to ignore.",
)
add_option("--coverage", action="store_true", help="Collect contract coverage.")
add_option("--project", action="store", help="Change Ape's project")

# NOTE: Other pytest plugins, such as hypothesis, should integrate with pytest separately

Expand Down Expand Up @@ -79,6 +80,9 @@ def is_module(v):
from ape.pytest.runners import PytestApeRunner
from ape.utils.basemodel import ManagerAccessMixin

if project := config.getoption("--project"):
ManagerAccessMixin.local_project.chdir(project)

# Register the custom Ape test runner
config_wrapper = ConfigWrapper(config)
receipt_capture = ReceiptCapture(config_wrapper)
Expand Down
11 changes: 11 additions & 0 deletions tests/functional/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,3 +1053,14 @@ def test_instance_map(self, project, vyper_contract_instance, mock_sepolia):
return

assert False, "Failed to find expected URI"


def test_chdir(project):
original_path = project.path
with create_tempdir() as new_path:
project.chdir(new_path)
assert project.path == new_path

# Undo.
project.chdir(original_path)
assert project.path == original_path
25 changes: 25 additions & 0 deletions tests/integration/cli/test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,28 @@ def test_watch(mocker, integ_project, runner, ape_cli):
assert result.exit_code == 0

runner_patch.assert_called_once_with((Path("contracts"), Path("tests")), 0.5, "-s")


@skip_projects_except("with-contracts")
def test_project_option(integ_project, ape_cli, runner):
_ = integ_project # NOTE: Not actually used, but avoid running across all projects.

# NOTE: Using isolated filesystem so that
with runner.isolated_filesystem():
# Setup a project
project_name = "test-token-project"
project_dir = Path.cwd() / project_name
tests_dir = project_dir / "tests"
tests_dir.mkdir(parents=True)

# Setup a test
test_file = tests_dir / "test_project_option.py"
test_text = """
def test_project_option():
assert True
""".lstrip()
test_file.write_text(test_text)

result = runner.invoke(ape_cli, ("test", "--project", f"./{project_name}"))
assert "1 passed" in result.output
assert result.exit_code == 0

0 comments on commit ed45b19

Please sign in to comment.