44The tests ensure that the projects build, configure, and execute correctly.
55"""
66
7+ import os
8+ import shutil
79import subprocess
810from pathlib import Path
911from tomllib import loads
@@ -21,41 +23,136 @@ class TestConanCMake:
2123 """Test project variation of conan and CMake"""
2224
2325 @staticmethod
24- def test_simple (example_runner : CliRunner ) -> None :
25- """Simple project"""
26- # Create project configuration
26+ def _create_project (skip_upload : bool = True ) -> Project :
27+ """Create a project instance with common configuration."""
2728 project_root = Path .cwd ()
28- project_configuration = ProjectConfiguration (project_root = project_root , version = None , verbosity = 2 , debug = True )
29-
30- # Create console interface
29+ config = ProjectConfiguration (project_root = project_root , version = None , verbosity = 2 , debug = True )
3130 interface = ConsoleInterface ()
3231
33- # Load pyproject.toml data
3432 pyproject_path = project_root / 'pyproject.toml'
3533 pyproject_data = loads (pyproject_path .read_text (encoding = 'utf-8' ))
3634
37- # Create and use the project directly
38- project = Project (project_configuration , interface , pyproject_data )
35+ if skip_upload :
36+ TestConanCMake ._ensure_conan_config (pyproject_data )
37+ pyproject_data ['tool' ]['cppython' ]['providers' ]['conan' ]['skip_upload' ] = True
3938
40- # Call install directly to get structured results
41- project .install ()
39+ return Project (config , interface , pyproject_data )
4240
43- # Run the CMake configuration command
41+ @staticmethod
42+ def _run_cmake_configure () -> None :
43+ """Run CMake configuration and assert success."""
4444 result = subprocess .run (['cmake' , '--preset=default' ], capture_output = True , text = True , check = False )
45+ assert result .returncode == 0 , f'CMake configuration failed: { result .stderr } '
46+
47+ @staticmethod
48+ def _run_cmake_build () -> None :
49+ """Run CMake build and assert success."""
50+ result = subprocess .run (['cmake' , '--build' , 'build' ], capture_output = True , text = True , check = False )
51+ assert result .returncode == 0 , f'CMake build failed: { result .stderr } '
52+
53+ @staticmethod
54+ def _verify_build_artifacts () -> Path :
55+ """Verify basic build artifacts exist and return build path."""
56+ build_path = Path ('build' ).absolute ()
57+ assert (build_path / 'CMakeCache.txt' ).exists (), f'CMakeCache.txt not found in { build_path } '
58+ return build_path
59+
60+ @staticmethod
61+ def _ensure_conan_config (pyproject_data : dict ) -> None :
62+ """Helper method to ensure Conan configuration exists in pyproject data"""
63+ if 'tool' not in pyproject_data :
64+ pyproject_data ['tool' ] = {}
65+ if 'cppython' not in pyproject_data ['tool' ]:
66+ pyproject_data ['tool' ]['cppython' ] = {}
67+ if 'providers' not in pyproject_data ['tool' ]['cppython' ]:
68+ pyproject_data ['tool' ]['cppython' ]['providers' ] = {}
69+ if 'conan' not in pyproject_data ['tool' ]['cppython' ]['providers' ]:
70+ pyproject_data ['tool' ]['cppython' ]['providers' ]['conan' ] = {}
71+
72+ @staticmethod
73+ def test_simple (example_runner : CliRunner ) -> None :
74+ """Simple project"""
75+ # Create project and install dependencies
76+ project = TestConanCMake ._create_project (skip_upload = False )
77+ project .install ()
4578
46- assert result .returncode == 0 , f'Cmake failed: { result .stderr } '
79+ # Configure and verify build
80+ TestConanCMake ._run_cmake_configure ()
81+ TestConanCMake ._verify_build_artifacts ()
4782
48- path = Path ('build' ).absolute ()
83+ # Test publishing with skip_upload enabled
84+ publish_project = TestConanCMake ._create_project (skip_upload = True )
85+ publish_project .publish ()
4986
50- # Verify that the build directory contains the expected files
51- assert (path / 'CMakeCache.txt' ).exists (), f'{ path / "CMakeCache.txt" } not found'
87+ @staticmethod
88+ def test_library (example_runner : CliRunner ) -> None :
89+ """Test library creation and packaging workflow"""
90+ # Create project and install dependencies
91+ project = TestConanCMake ._create_project (skip_upload = False )
92+ project .install ()
5293
53- # --- Setup for Publish with modified config ---
54- # Modify the in-memory representation of the pyproject data
55- pyproject_data ['tool' ]['cppython' ]['providers' ]['conan' ]['skip_upload' ] = True
94+ # Configure, build, and verify
95+ TestConanCMake ._run_cmake_configure ()
96+ TestConanCMake ._run_cmake_build ()
97+ build_path = TestConanCMake ._verify_build_artifacts ()
5698
57- # Create a new project instance with the modified configuration for the 'publish' step
58- publish_project = Project (project_configuration , interface , pyproject_data )
99+ # Verify library files exist (platform-specific)
100+ lib_files = list (build_path .glob ('**/libmathutils.*' )) + list (build_path .glob ('**/mathutils.lib' ))
101+ assert len (lib_files ) > 0 , f'No library files found in { build_path } '
59102
60- # Publish the project to the local cache
103+ # Package the library to local cache
104+ publish_project = TestConanCMake ._create_project (skip_upload = True )
61105 publish_project .publish ()
106+
107+ @staticmethod
108+ def _publish_library_to_cache () -> None :
109+ """Helper method to publish the library to local Conan cache"""
110+ examples_root = Path (__file__ ).parent .parent .parent .parent / 'examples'
111+ library_source = examples_root / 'conan_cmake' / 'library'
112+ library_temp = Path ('temp_library' )
113+
114+ # Copy library to temp location
115+ shutil .copytree (library_source , library_temp )
116+
117+ # Change to library directory and publish it
118+ original_cwd = Path .cwd ()
119+ try :
120+ os .chdir (library_temp )
121+
122+ # Create and configure library project
123+ lib_project = TestConanCMake ._create_project (skip_upload = True )
124+ lib_project .install ()
125+
126+ # Build and publish library
127+ TestConanCMake ._run_cmake_configure ()
128+ TestConanCMake ._run_cmake_build ()
129+ lib_project .publish ()
130+
131+ finally :
132+ os .chdir (original_cwd )
133+
134+ @staticmethod
135+ def test_library_consumer (example_runner : CliRunner ) -> None :
136+ """Test that a consumer can use the published library"""
137+ # First, publish the library to the local cache
138+ TestConanCMake ._publish_library_to_cache ()
139+
140+ # Create consumer project and install dependencies
141+ consumer_project = TestConanCMake ._create_project (skip_upload = False )
142+ consumer_project .install ()
143+
144+ # Configure and build the consumer
145+ TestConanCMake ._run_cmake_configure ()
146+ TestConanCMake ._run_cmake_build ()
147+ build_path = TestConanCMake ._verify_build_artifacts ()
148+
149+ # Verify the executable was created and works
150+ exe_files = list (build_path .glob ('**/consumer*' ))
151+ assert len (exe_files ) > 0 , f'No consumer executable found in { build_path } '
152+
153+ # Run the consumer to verify it works
154+ exe_path = next ((f for f in exe_files if f .suffix == '.exe' or f .is_file ()), None )
155+ if exe_path :
156+ result = subprocess .run ([str (exe_path )], capture_output = True , text = True , check = False )
157+ assert result .returncode == 0 , f'Consumer execution failed: { result .stderr } '
158+ assert 'MathUtils' in result .stdout , f'Expected MathUtils output not found: { result .stdout } '
0 commit comments