@@ -142,6 +142,64 @@ def test_process_env_create() -> None:
142142 nox .virtualenv .ProcessEnv () # type: ignore[abstract]
143143
144144
145+ def test_process_env_get_env_with_bin_paths () -> None :
146+ penv = nox .virtualenv .PassthroughEnv (bin_paths = ["/test/bin" ])
147+ env = penv ._get_env ({})
148+ path = env .get ("PATH" )
149+ assert path
150+ assert "/test/bin" in path
151+
152+
153+ def test_process_env_get_env_exclude_outer () -> None :
154+ penv = nox .virtualenv .PassthroughEnv (bin_paths = ["/test/bin" ], env = {"TEST" : "value" })
155+ env = penv ._get_env ({}, include_outer_env = False )
156+ assert env ["TEST" ] == "value"
157+ assert env ["PATH" ] == "/test/bin"
158+
159+
160+ def test_ensure_gitignore_creates_file (tmp_path : Path ) -> None :
161+ envdir = tmp_path .joinpath (".nox" )
162+ location = envdir .joinpath ("session" )
163+
164+ nox .virtualenv ._ensure_gitignore (location .parent )
165+
166+ assert envdir .joinpath (".gitignore" ).read_text (encoding = "utf-8" ) == "*\n "
167+
168+
169+ def test_ensure_cachedir_tag_creates_file (tmp_path : Path ) -> None :
170+ envdir = tmp_path .joinpath (".nox" )
171+ location = envdir .joinpath ("session" )
172+
173+ nox .virtualenv ._ensure_cachedir_tag (location .parent )
174+
175+ assert (
176+ envdir .joinpath ("CACHEDIR.TAG" ).read_text (encoding = "utf-8" )
177+ == "Signature: 8a477f597d28d172789f06886806bc55\n "
178+ )
179+
180+
181+ def test_ensure_parent_gitignore_keeps_existing_file (tmp_path : Path ) -> None :
182+ envdir = tmp_path .joinpath (".nox" )
183+ envdir .mkdir ()
184+ gitignore = envdir .joinpath (".gitignore" )
185+ gitignore .write_text ("!keep\n " , encoding = "utf-8" )
186+
187+ nox .virtualenv ._ensure_gitignore (envdir )
188+
189+ assert gitignore .read_text (encoding = "utf-8" ) == "!keep\n "
190+
191+
192+ def test_ensure_parent_cachedir_tag_keeps_existing_file (tmp_path : Path ) -> None :
193+ envdir = tmp_path .joinpath (".nox" )
194+ envdir .mkdir ()
195+ cachedir_tag = envdir .joinpath ("CACHEDIR.TAG" )
196+ cachedir_tag .write_text ("!keep\n " , encoding = "utf-8" )
197+
198+ nox .virtualenv ._ensure_cachedir_tag (envdir )
199+
200+ assert cachedir_tag .read_text (encoding = "utf-8" ) == "!keep\n "
201+
202+
145203def test_invalid_venv_create (
146204 make_one : Callable [
147205 ..., tuple [nox .virtualenv .VirtualEnv | nox .virtualenv .ProcessEnv , Path ]
@@ -151,6 +209,100 @@ def test_invalid_venv_create(
151209 make_one (venv_backend = "invalid" )
152210
153211
212+ def test_get_virtualenv_invalid_backend (
213+ tmp_path : Path ,
214+ ) -> None :
215+ with pytest .raises (ValueError , match = "Expected venv_backend one of" ):
216+ nox .virtualenv .get_virtualenv (
217+ "invalid" ,
218+ download_python = "auto" ,
219+ envdir = str (tmp_path ),
220+ reuse_existing = False ,
221+ )
222+
223+
224+ def test_get_virtualenv_fallback_to_available_backend (
225+ tmp_path : Path ,
226+ monkeypatch : pytest .MonkeyPatch ,
227+ ) -> None :
228+ # Force optional backends to be unavailable so fallback behavior is deterministic.
229+ monkeypatch .setattr (
230+ nox .virtualenv ,
231+ "OPTIONAL_VENVS" ,
232+ {"conda" : False , "mamba" : False , "micromamba" : False , "uv" : False },
233+ )
234+ venv = nox .virtualenv .get_virtualenv (
235+ "conda" ,
236+ "mamba" ,
237+ "venv" ,
238+ download_python = "auto" ,
239+ envdir = str (tmp_path ),
240+ reuse_existing = False ,
241+ )
242+ assert isinstance (venv , nox .virtualenv .VirtualEnv )
243+ assert venv .venv_backend == "venv"
244+
245+
246+ def test_get_virtualenv_no_backends_available (
247+ tmp_path : Path ,
248+ monkeypatch : pytest .MonkeyPatch ,
249+ ) -> None :
250+ # Simulate no optional backends present.
251+ monkeypatch .setattr (
252+ nox .virtualenv ,
253+ "OPTIONAL_VENVS" ,
254+ {"conda" : False , "mamba" : False , "micromamba" : False , "uv" : False },
255+ )
256+ with pytest .raises (ValueError , match = "No backends present" ):
257+ nox .virtualenv .get_virtualenv (
258+ "conda" ,
259+ "mamba" ,
260+ download_python = "auto" ,
261+ envdir = str (tmp_path ),
262+ reuse_existing = False ,
263+ )
264+
265+
266+ def test_get_virtualenv_none_backend (
267+ tmp_path : Path ,
268+ ) -> None :
269+ venv = nox .virtualenv .get_virtualenv (
270+ "none" ,
271+ download_python = "auto" ,
272+ envdir = str (tmp_path ),
273+ reuse_existing = False ,
274+ )
275+ assert isinstance (venv , nox .virtualenv .ProcessEnv )
276+
277+
278+ def test_get_virtualenv_interpreter_false (
279+ tmp_path : Path ,
280+ ) -> None :
281+ venv = nox .virtualenv .get_virtualenv (
282+ "venv" ,
283+ download_python = "auto" ,
284+ envdir = str (tmp_path ),
285+ reuse_existing = False ,
286+ interpreter = False ,
287+ )
288+ assert isinstance (venv , nox .virtualenv .ProcessEnv )
289+
290+
291+ def test_get_virtualenv_non_optional_fallback (
292+ tmp_path : Path ,
293+ ) -> None :
294+ with pytest .raises (
295+ ValueError , match = r"Only optional backends.*may have a fallback"
296+ ):
297+ nox .virtualenv .get_virtualenv (
298+ "venv" ,
299+ "uv" ,
300+ download_python = "auto" ,
301+ envdir = str (tmp_path ),
302+ reuse_existing = False ,
303+ )
304+
305+
154306def test_condaenv_constructor_defaults (
155307 make_conda : Callable [..., tuple [CondaEnv , Path ]],
156308) -> None :
0 commit comments