@@ -52,3 +52,146 @@ def test_create_arches_directory_exists(tmp_path: pathlib.Path) -> None:
5252 with patch ("relenv.create.arches" , mocked_arches ):
5353 with pytest .raises (CreateException ):
5454 create ("foo" , dest = tmp_path )
55+
56+
57+ def test_create_with_minor_version (tmp_path : pathlib .Path ) -> None :
58+ """Test that minor version (e.g., '3.12') resolves to latest micro version."""
59+ import argparse
60+ import sys
61+
62+ from relenv .create import main
63+ from relenv .pyversions import Version
64+
65+ # Mock python_versions to return some test versions
66+ all_versions = {
67+ Version ("3.11.5" ): "aaa111" ,
68+ Version ("3.12.5" ): "abc123" ,
69+ Version ("3.12.6" ): "def456" ,
70+ Version ("3.12.7" ): "ghi789" ,
71+ Version ("3.13.1" ): "zzz999" ,
72+ }
73+
74+ def mock_python_versions (minor : str | None = None ) -> dict [Version , str ]:
75+ """Mock that filters versions by minor version like the real function."""
76+ if minor is None :
77+ return all_versions
78+ # Filter versions matching the minor version
79+ mv = Version (minor )
80+ return {
81+ v : h
82+ for v , h in all_versions .items ()
83+ if v .major == mv .major and v .minor == mv .minor
84+ }
85+
86+ # Create a fake archive
87+ to_be_archived = tmp_path / "to_be_archived"
88+ to_be_archived .mkdir ()
89+ test_file = to_be_archived / "testfile"
90+ test_file .touch ()
91+ tar_file = tmp_path / "fake_archive"
92+ with tarfile .open (str (tar_file ), "w:xz" ) as tar :
93+ tar .add (str (to_be_archived ), to_be_archived .name )
94+
95+ # Use appropriate architecture for the platform
96+ test_arch = "amd64" if sys .platform == "win32" else "x86_64"
97+ args = argparse .Namespace (name = "test_env" , arch = test_arch , python = "3.12" )
98+
99+ with chdir (str (tmp_path )):
100+ with patch ("relenv.create.python_versions" , side_effect = mock_python_versions ):
101+ with patch ("relenv.create.archived_build" , return_value = tar_file ):
102+ with patch ("relenv.create.build_arch" , return_value = test_arch ):
103+ main (args )
104+
105+ to_dir = tmp_path / "test_env"
106+ assert to_dir .exists ()
107+
108+
109+ def test_create_with_full_version (tmp_path : pathlib .Path ) -> None :
110+ """Test that full version (e.g., '3.12.7') still works."""
111+ import argparse
112+ import sys
113+
114+ from relenv .create import main
115+ from relenv .pyversions import Version
116+
117+ # Mock python_versions to return some test versions
118+ all_versions = {
119+ Version ("3.11.5" ): "aaa111" ,
120+ Version ("3.12.5" ): "abc123" ,
121+ Version ("3.12.6" ): "def456" ,
122+ Version ("3.12.7" ): "ghi789" ,
123+ Version ("3.13.1" ): "zzz999" ,
124+ }
125+
126+ def mock_python_versions (minor : str | None = None ) -> dict [Version , str ]:
127+ """Mock that filters versions by minor version like the real function."""
128+ if minor is None :
129+ return all_versions
130+ # Filter versions matching the minor version
131+ mv = Version (minor )
132+ return {
133+ v : h
134+ for v , h in all_versions .items ()
135+ if v .major == mv .major and v .minor == mv .minor
136+ }
137+
138+ # Create a fake archive
139+ to_be_archived = tmp_path / "to_be_archived"
140+ to_be_archived .mkdir ()
141+ test_file = to_be_archived / "testfile"
142+ test_file .touch ()
143+ tar_file = tmp_path / "fake_archive"
144+ with tarfile .open (str (tar_file ), "w:xz" ) as tar :
145+ tar .add (str (to_be_archived ), to_be_archived .name )
146+
147+ # Use appropriate architecture for the platform
148+ test_arch = "amd64" if sys .platform == "win32" else "x86_64"
149+ args = argparse .Namespace (name = "test_env" , arch = test_arch , python = "3.12.7" )
150+
151+ with chdir (str (tmp_path )):
152+ with patch ("relenv.create.python_versions" , side_effect = mock_python_versions ):
153+ with patch ("relenv.create.archived_build" , return_value = tar_file ):
154+ with patch ("relenv.create.build_arch" , return_value = test_arch ):
155+ main (args )
156+
157+ to_dir = tmp_path / "test_env"
158+ assert to_dir .exists ()
159+
160+
161+ def test_create_with_unknown_minor_version (tmp_path : pathlib .Path ) -> None :
162+ """Test that unknown minor version produces an error."""
163+ import argparse
164+ import sys
165+
166+ from relenv .create import main
167+ from relenv .pyversions import Version
168+
169+ # Mock python_versions to return empty dict for unknown version
170+ all_versions = {
171+ Version ("3.11.5" ): "aaa111" ,
172+ Version ("3.12.5" ): "abc123" ,
173+ Version ("3.12.6" ): "def456" ,
174+ Version ("3.12.7" ): "ghi789" ,
175+ Version ("3.13.1" ): "zzz999" ,
176+ }
177+
178+ # Use appropriate architecture for the platform
179+ test_arch = "amd64" if sys .platform == "win32" else "x86_64"
180+ args = argparse .Namespace (name = "test_env" , arch = test_arch , python = "3.99" )
181+
182+ def mock_python_versions (minor : str | None = None ) -> dict [Version , str ]:
183+ """Mock that filters versions by minor version like the real function."""
184+ if minor is None :
185+ return all_versions
186+ # Filter versions matching the minor version
187+ mv = Version (minor )
188+ return {
189+ v : h
190+ for v , h in all_versions .items ()
191+ if v .major == mv .major and v .minor == mv .minor
192+ }
193+
194+ with patch ("relenv.create.python_versions" , side_effect = mock_python_versions ):
195+ with patch ("relenv.create.build_arch" , return_value = test_arch ):
196+ with pytest .raises (SystemExit ):
197+ main (args )
0 commit comments