Skip to content

Commit

Permalink
feat: project flag on test cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Dec 9, 2024
1 parent abbe95e commit 8a37ce8
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
13 changes: 12 additions & 1 deletion src/ape/cli/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,21 @@ def project_option(**kwargs):
if (isinstance(_type, type) and issubclass(_type, Path))
else _project_callback
)
cd = kwargs.pop("cd", False)

def callback_wrapper(ctx, param, val):
result = callback(ctx, param, val)
if cd:
# The CLI requested we also change directories into this path.
path = getattr(result, "path", result) # project.path or path
ctx.obj.local_project.chdir(path.expanduser().resolve())

return result

return click.option(
"--project",
help="The path to a local project or manifest",
callback=callback,
callback=callback_wrapper,
metavar="PATH",
is_eager=True,
**kwargs,
Expand Down
19 changes: 19 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,24 @@ def clean(self):
self.sources._path_cache = None
self._clear_cached_config()

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

os.chdir(path)
new_local_project = LocalProject(path)
ManagerAccessMixin.local_project._cache = new_local_project
return new_local_project

def reload_config(self):
"""
Reload the local ape-config.yaml file.
Expand Down
5 changes: 3 additions & 2 deletions src/ape_test/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pytest
from click import Command

from ape.cli.options import ape_cli_context
from ape.cli.options import ape_cli_context, project_option
from ape.logging import LogLevel, _get_level


Expand Down Expand Up @@ -79,6 +79,7 @@ def parse_args(self, ctx, args: list[str]) -> list[str]:
@ape_cli_context(
default_log_level=LogLevel.WARNING.value,
)
@project_option(type=Path, cd=True)
@click.option(
"-w",
"--watch",
Expand All @@ -103,7 +104,7 @@ def parse_args(self, ctx, args: list[str]) -> list[str]:
help="Delay between polling cycles for `ape test --watch`. Defaults to 0.5 seconds.",
)
@click.argument("pytest_args", nargs=-1, type=click.UNPROCESSED)
def cli(cli_ctx, watch, watch_folders, watch_delay, pytest_args):
def cli(cli_ctx, project, watch, watch_folders, watch_delay, pytest_args):
pytest_arg_ls = [*pytest_args]
if pytest_verbosity := cli_ctx.get("pytest_verbosity"):
pytest_arg_ls.append(pytest_verbosity)
Expand Down
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 8a37ce8

Please sign in to comment.