11from __future__ import annotations
22
3+ import textwrap
4+
35from pathlib import Path
46from typing import TYPE_CHECKING
57
810from cleo .testers .application_tester import ApplicationTester
911
1012from poetry .console .application import Application
13+ from poetry .console .commands .version import VersionCommand
14+ from tests .helpers import switch_working_directory
1115
1216
1317if TYPE_CHECKING :
18+ from pytest import TempPathFactory
19+ from pytest_mock import MockerFixture
20+
1421 from tests .types import FixtureCopier
1522
1623
@@ -24,6 +31,21 @@ def tester() -> ApplicationTester:
2431 return ApplicationTester (Application ())
2532
2633
34+ @pytest .fixture
35+ def with_mocked_version_command (mocker : MockerFixture ) -> None :
36+ orig_version_command = VersionCommand .handle
37+
38+ def mock_handle (command : VersionCommand ) -> int :
39+ exit_code = orig_version_command (command )
40+
41+ command .io .write_line (f"ProjectPath: { command .poetry .pyproject_path .parent } " )
42+ command .io .write_line (f"WorkingDirectory: { Path .cwd ()} " )
43+
44+ return exit_code
45+
46+ mocker .patch ("poetry.console.commands.version.VersionCommand.handle" , mock_handle )
47+
48+
2749@pytest .mark .parametrize ("parameter" , ["-C" , "--directory" , "-P" , "--project" ])
2850def test_application_global_option_position_does_not_matter (
2951 parameter : str , tester : ApplicationTester , project_source_directory : Path
@@ -58,3 +80,62 @@ def test_application_global_option_position_does_not_matter(
5880
5981 assert "certifi" in stdout
6082 assert len (stdout .splitlines ()) == 8
83+
84+
85+ @pytest .mark .parametrize ("parameter" , ["project" , "directory" ])
86+ def test_application_with_context_parameters (
87+ parameter : str ,
88+ tester : ApplicationTester ,
89+ project_source_directory : Path ,
90+ with_mocked_version_command : None ,
91+ ) -> None :
92+ # ensure pre-conditions are met
93+ assert project_source_directory != Path .cwd ()
94+
95+ is_directory_param = parameter == "directory"
96+
97+ tester .execute (f"--{ parameter } { project_source_directory } version" )
98+ assert tester .io .fetch_error () == ""
99+ assert tester .status_code == 0
100+
101+ output = tester .io .fetch_output ()
102+ assert output == textwrap .dedent (f"""\
103+ foobar 0.1.0
104+ ProjectPath: { project_source_directory }
105+ WorkingDirectory: { project_source_directory if is_directory_param else Path .cwd ()}
106+ """ )
107+
108+
109+ def test_application_with_relative_project_parameter (
110+ tester : ApplicationTester ,
111+ project_source_directory : Path ,
112+ with_mocked_version_command : None ,
113+ tmp_path_factory : TempPathFactory ,
114+ ) -> None :
115+ # ensure pre-conditions are met
116+ cwd = Path .cwd ()
117+ assert project_source_directory .is_relative_to (cwd )
118+
119+ # construct relative path
120+ relative_source_directory = project_source_directory .relative_to (cwd )
121+ assert relative_source_directory .as_posix () != project_source_directory .as_posix ()
122+ assert not relative_source_directory .is_absolute ()
123+
124+ # we expect application run to be executed within current cwd but project to be a subdirectory
125+ args = f"--directory '{ cwd } ' --project { relative_source_directory } version"
126+
127+ # we switch cwd to a new temporary directory unrelated to the project directory
128+ new_working_dir = tmp_path_factory .mktemp ("unrelated-working-directory" )
129+ with switch_working_directory (new_working_dir ):
130+ assert Path .cwd () == new_working_dir
131+
132+ tester .execute (args )
133+ assert tester .io .fetch_error () == ""
134+ assert tester .status_code == 0
135+
136+ output = tester .io .fetch_output ()
137+ assert output == textwrap .dedent (f"""\
138+ foobar 0.1.0
139+ ProjectPath: { project_source_directory }
140+ WorkingDirectory: { cwd }
141+ """ )
0 commit comments