11from __future__ import annotations
22
33import os .path
4- import shutil
4+ from unittest import mock
55
66import pytest
77
8+ import pre_commit .constants as C
89from pre_commit import envcontext
10+ from pre_commit import lang_base
911from pre_commit .languages import r
1012from pre_commit .prefix import Prefix
1113from pre_commit .store import _make_local_repo
14+ from pre_commit .util import resource_text
1215from pre_commit .util import win_exe
1316from testing .language_helpers import run_language
1417
@@ -127,7 +130,8 @@ def test_path_rscript_exec_no_r_home_set():
127130 assert r ._rscript_exec () == 'Rscript'
128131
129132
130- def test_r_hook (tmp_path ):
133+ @pytest .fixture
134+ def renv_lock_file (tmp_path ):
131135 renv_lock = '''\
132136 {
133137 "R": {
@@ -157,6 +161,12 @@ def test_r_hook(tmp_path):
157161 }
158162}
159163'''
164+ tmp_path .joinpath ('renv.lock' ).write_text (renv_lock )
165+ yield
166+
167+
168+ @pytest .fixture
169+ def description_file (tmp_path ):
160170 description = '''\
161171 Package: gli.clu
162172Title: What the Package Does (One Line, Title Case)
@@ -178,27 +188,39 @@ def test_r_hook(tmp_path):
178188Imports:
179189 rprojroot
180190'''
181- hello_world_r = '''\
191+ tmp_path .joinpath ('DESCRIPTION' ).write_text (description )
192+ yield
193+
194+
195+ @pytest .fixture
196+ def hello_world_file (tmp_path ):
197+ hello_world = '''\
182198 stopifnot(
183199 packageVersion('rprojroot') == '1.0',
184200 packageVersion('gli.clu') == '0.0.0.9000'
185201)
186202cat("Hello, World, from R!\n ")
187203'''
204+ tmp_path .joinpath ('hello-world.R' ).write_text (hello_world )
205+ yield
188206
189- tmp_path . joinpath ( 'renv.lock' ). write_text ( renv_lock )
190- tmp_path . joinpath ( 'DESCRIPTION' ). write_text ( description )
191- tmp_path . joinpath ( 'hello-world.R' ). write_text ( hello_world_r )
207+
208+ @ pytest . fixture
209+ def renv_folder ( tmp_path ):
192210 renv_dir = tmp_path .joinpath ('renv' )
193211 renv_dir .mkdir ()
194- shutil .copy (
195- os .path .join (
196- os .path .dirname (__file__ ),
197- '../../pre_commit/resources/empty_template_activate.R' ,
198- ),
199- renv_dir .joinpath ('activate.R' ),
200- )
212+ activate_r = resource_text ('empty_template_activate.R' )
213+ renv_dir .joinpath ('activate.R' ).write_text (activate_r )
214+ yield
215+
201216
217+ def test_r_hook (
218+ tmp_path ,
219+ renv_lock_file ,
220+ description_file ,
221+ hello_world_file ,
222+ renv_folder ,
223+ ):
202224 expected = (0 , b'Hello, World, from R!\n ' )
203225 assert run_language (tmp_path , r , 'Rscript hello-world.R' ) == expected
204226
@@ -221,3 +243,55 @@ def test_r_inline(tmp_path):
221243 args = ('hi' , 'hello' ),
222244 )
223245 assert ret == (0 , b'hi, hello, from R!\n ' )
246+
247+
248+ @pytest .fixture
249+ def prefix (tmpdir ):
250+ yield Prefix (str (tmpdir ))
251+
252+
253+ @pytest .fixture
254+ def installed_environment (
255+ renv_lock_file ,
256+ hello_world_file ,
257+ renv_folder ,
258+ prefix ,
259+ ):
260+ env_dir = lang_base .environment_dir (
261+ prefix , r .ENVIRONMENT_DIR , r .get_default_version (),
262+ )
263+ r .install_environment (prefix , C .DEFAULT , ())
264+ yield prefix , env_dir
265+
266+
267+ def test_health_check_healthy (installed_environment ):
268+ # should be healthy right after creation
269+ prefix , _ = installed_environment
270+ assert r .health_check (prefix , C .DEFAULT ) is None
271+
272+
273+ def test_health_check_after_downgrade (installed_environment ):
274+ prefix , _ = installed_environment
275+
276+ # pretend the saved installed version is old
277+ with mock .patch .object (r , '_read_installed_version' , return_value = '1.0.0' ):
278+ output = r .health_check (prefix , C .DEFAULT )
279+
280+ assert output is not None
281+ assert output .startswith ('Hooks were installed for R version' )
282+
283+
284+ @pytest .mark .parametrize ('version' , ('NULL' , 'NA' , "''" ))
285+ def test_health_check_without_version (prefix , installed_environment , version ):
286+ prefix , env_dir = installed_environment
287+
288+ # simulate old pre-commit install by unsetting the installed version
289+ r ._execute_vanilla_r_code_as_script (
290+ f'renv::settings$r.version({ version } )' ,
291+ prefix = prefix , version = C .DEFAULT , cwd = env_dir ,
292+ )
293+
294+ # no R version specified fails as unhealty
295+ msg = 'Hooks were installed with an unknown R version'
296+ check_output = r .health_check (prefix , C .DEFAULT )
297+ assert check_output is not None and check_output .startswith (msg )
0 commit comments