66
77import pytest
88from packaging .requirements import Requirement
9+ from pytest_mock import MockerFixture
910
1011from cppython .plugins .conan .plugin import ConanProvider
1112from cppython .test .pytest .mixins import ProviderPluginTestMixin
13+ from cppython .utility .exception import ProviderInstallationError
1214
1315# Use shared fixtures
1416pytest_plugins = ['tests.fixtures.conan' ]
@@ -44,21 +46,27 @@ def fixture_plugin_type() -> type[ConanProvider]:
4446
4547 def test_install_with_dependencies (
4648 self ,
49+ mocker : MockerFixture ,
4750 plugin : ConanProvider ,
48- conan_mock_api : Mock ,
4951 conan_temp_conanfile : Path ,
5052 conan_mock_dependencies : list [Requirement ],
5153 conan_setup_mocks : dict [str , Mock ],
5254 ) -> None :
5355 """Test install method with dependencies and existing conanfile
5456
5557 Args:
58+ mocker: Pytest mocker fixture
5659 plugin: The plugin instance
57- conan_mock_api: Mock ConanAPI instance
5860 conan_temp_conanfile: Path to temporary conanfile.py
5961 conan_mock_dependencies: List of mock dependencies
6062 conan_setup_mocks: Dictionary containing all mocks
6163 """
64+ # Setup subprocess mock to return success
65+ mock_subprocess = mocker .patch ('cppython.plugins.conan.plugin.subprocess.run' )
66+ mock_subprocess .return_value .returncode = 0
67+ mock_subprocess .return_value .stdout = 'Install completed successfully'
68+ mock_subprocess .return_value .stderr = ''
69+
6270 # Setup dependencies
6371 plugin .core_data .cppython_data .dependencies = conan_mock_dependencies
6472
@@ -79,124 +87,55 @@ def test_install_with_dependencies(
7987 # Verify build path was created
8088 assert plugin .core_data .cppython_data .build_path .exists ()
8189
82- # Verify Conan API calls
83- conan_mock_api .profiles .get_default_host .assert_called_once ()
84- conan_mock_api .profiles .get_default_build .assert_called_once ()
85- conan_mock_api .profiles .get_profile .assert_called ()
86- conan_mock_api .graph .load_graph_consumer .assert_called_once ()
87- conan_mock_api .install .install_binaries .assert_called_once ()
88-
89- # Verify graph consumer call arguments
90- load_graph_args = conan_mock_api .graph .load_graph_consumer .call_args
91- assert load_graph_args [1 ]['path' ] == str (conan_temp_conanfile )
92- assert load_graph_args [1 ]['update' ] is False
93- assert load_graph_args [1 ]['check_updates' ] is False
94-
95- def test_install_without_conanfile (
96- self ,
97- plugin : ConanProvider ,
98- conan_mock_api : Mock ,
99- conan_mock_dependencies : list [Requirement ],
100- conan_setup_mocks : dict [str , Mock ],
101- ) -> None :
102- """Test install method when conanfile.py doesn't exist
103-
104- Args:
105- plugin: The plugin instance
106- conan_mock_api: Mock ConanAPI instance
107- conan_mock_dependencies: List of mock dependencies
108- conan_setup_mocks: Dictionary containing all mocks
109- """
110- # Setup dependencies
111- plugin .core_data .cppython_data .dependencies = [conan_mock_dependencies [0 ]]
112-
113- # Execute
114- plugin .install ()
115-
116- # Verify builder was called
117- conan_setup_mocks ['builder' ].generate_conanfile .assert_called_once ()
118-
119- # Verify build path was created
120- assert plugin .core_data .cppython_data .build_path .exists ()
121-
122- # Verify Conan API calls were NOT made (no conanfile.py)
123- conan_mock_api .profiles .get_default_host .assert_not_called ()
124- conan_mock_api .profiles .get_default_build .assert_not_called ()
125- conan_mock_api .profiles .get_profile .assert_not_called ()
126- conan_mock_api .graph .load_graph_consumer .assert_not_called ()
127- conan_mock_api .install .install_binaries .assert_not_called ()
128-
129- def test_install_no_dependencies (
130- self ,
131- plugin : ConanProvider ,
132- conan_mock_api : Mock ,
133- conan_temp_conanfile : Path ,
134- conan_setup_mocks : dict [str , Mock ],
135- ) -> None :
136- """Test install method with no dependencies
90+ # Verify subprocess was called with correct command
91+ mock_subprocess .assert_called_once ()
92+ call_args = mock_subprocess .call_args
93+ cmd = call_args [0 ][0 ]
13794
138- Args:
139- plugin: The plugin instance
140- conan_mock_api: Mock ConanAPI instance
141- conan_temp_conanfile: Path to temporary conanfile.py
142- conan_setup_mocks: Dictionary containing all mocks
143- """
144- # No dependencies
145- plugin .core_data .cppython_data .dependencies = []
146-
147- # Execute
148- plugin .install ()
149-
150- # Verify builder was called with empty dependencies
151- conan_setup_mocks ['builder' ].generate_conanfile .assert_called_once ()
152- assert len (conan_setup_mocks ['builder' ].generate_conanfile .call_args [0 ][1 ]) == 0
153-
154- # Verify dependency resolution was not called
155- conan_setup_mocks ['resolve_conan_dependency' ].assert_not_called ()
156-
157- # Verify build path was created
158- assert plugin .core_data .cppython_data .build_path .exists ()
95+ # Check command structure
96+ assert cmd [0 ] == 'conan'
97+ assert cmd [1 ] == 'install'
98+ assert cmd [2 ] == str (conan_temp_conanfile )
99+ assert '--output-folder' in cmd
100+ assert '--build' in cmd
101+ assert 'missing' in cmd
102+ assert '--update' not in cmd # install mode, not update
159103
160- # Verify Conan API calls were still made (conanfile.py exists)
161- conan_mock_api .profiles .get_default_host .assert_called_once ()
162- conan_mock_api .profiles .get_default_build .assert_called_once ()
163- conan_mock_api .profiles .get_profile .assert_called ()
164- conan_mock_api .graph .load_graph_consumer .assert_called_once ()
165- conan_mock_api .install .install_binaries .assert_called_once ()
104+ # Check working directory
105+ assert call_args [1 ]['cwd' ] == str (plugin .core_data .project_data .project_root )
166106
167- def test_install_conan_api_failure (
107+ def test_install_conan_command_failure (
168108 self ,
109+ mocker : MockerFixture ,
169110 plugin : ConanProvider ,
170- conan_mock_api : Mock ,
171111 conan_temp_conanfile : Path ,
172112 conan_mock_dependencies : list [Requirement ],
173113 conan_setup_mocks : dict [str , Mock ],
174114 ) -> None :
175- """Test install method when Conan API calls fail
115+ """Test install method when conan command fails
176116
177117 Args:
118+ mocker: Pytest mocker fixture
178119 plugin: The plugin instance
179- conan_mock_api: Mock ConanAPI instance
180120 conan_temp_conanfile: Path to temporary conanfile.py
181121 conan_mock_dependencies: List of mock dependencies
182122 conan_setup_mocks: Dictionary containing all mocks
183123 """
184- # Make API call fail
185- conan_mock_api .graph .load_graph_consumer .side_effect = Exception ('Conan graph load failed' )
124+ # Make subprocess return failure
125+ mock_subprocess = mocker .patch ('cppython.plugins.conan.plugin.subprocess.run' )
126+ mock_subprocess .return_value .returncode = 1
127+ mock_subprocess .return_value .stdout = ''
128+ mock_subprocess .return_value .stderr = 'Conan install failed: package not found'
186129
187130 # Add a dependency
188131 plugin .core_data .cppython_data .dependencies = [conan_mock_dependencies [0 ]]
189132
190133 # Execute and verify exception is raised
191- with pytest .raises (Exception , match = 'Conan graph load failed' ):
134+ with pytest .raises (ProviderInstallationError , match = 'Conan install failed with return code 1 ' ):
192135 plugin .install ()
193136
194137 # Verify builder was still called
195138 conan_setup_mocks ['builder' ].generate_conanfile .assert_called_once ()
196139
197- # Verify API was called up to the point of failure
198- conan_mock_api .profiles .get_default_host .assert_called_once ()
199- conan_mock_api .profiles .get_default_build .assert_called_once ()
200- conan_mock_api .profiles .get_profile .assert_called ()
201- conan_mock_api .graph .load_graph_consumer .assert_called_once ()
202- conan_mock_api .install .install_binaries .assert_not_called ()
140+ # Verify subprocess was called
141+ mock_subprocess .assert_called_once ()
0 commit comments