diff --git a/news/print-profiles-test.rst b/news/print-profiles-test.rst new file mode 100644 index 0000000..c7cead8 --- /dev/null +++ b/news/print-profiles-test.rst @@ -0,0 +1,23 @@ +**Added:** + +* Add test for ``print_profiles``. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/cmi/profilesmanager.py b/src/diffpy/cmi/profilesmanager.py index bb19edf..090d4f7 100644 --- a/src/diffpy/cmi/profilesmanager.py +++ b/src/diffpy/cmi/profilesmanager.py @@ -26,11 +26,26 @@ presence_check, ) from diffpy.cmi.log import plog -from diffpy.cmi.packsmanager import PacksManager +from diffpy.cmi.packsmanager import PacksManager, get_package_dir __all__ = ["Profile", "ProfilesManager"] +def _installed_profiles_dir(root_path=None) -> Path: + """Locate requirements/profiles/ for the installed package.""" + with get_package_dir(root_path) as pkgdir: + pkg = Path(pkgdir).resolve() + for c in ( + pkg / "requirements" / "profiles", + pkg.parents[2] / "requirements" / "profiles", + ): + if c.is_dir(): + return c + raise FileNotFoundError( + "Could not locate requirements/profiles. Check your installation." + ) + + @dataclass class Profile: """Container for a resolved profile. @@ -78,9 +93,14 @@ class ProfilesManager: Defaults to `requirements/profiles` under the installed package. """ - def __init__(self, packs_mgr: Optional[PacksManager] = None) -> None: - self.packs_mgr = packs_mgr or PacksManager() - self.profiles_dir = self.packs_mgr.packs_dir.parent / "profiles" + def __init__( + self, + packs_mgr: Optional[PacksManager] = None, + root_path=None, + ) -> None: + + self.packs_mgr = packs_mgr or PacksManager(root_path=root_path) + self.profiles_dir = _installed_profiles_dir(root_path) # Resolution & loading def _resolve_profile_file(self, identifier: Union[str, Path]) -> Path: diff --git a/tests/conftest.py b/tests/conftest.py index af72bd5..6f8d937 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -93,13 +93,30 @@ def example_cases(tmp_path_factory): case5e.mkdir(parents=True, exist_ok=True) (case5e / "script5.py").write_text(f"# {case5e.name} script5\n") - case5req_dir = root_temp_dir / "case5" / "requirements" / "packs" - case5req_dir.mkdir(parents=True, exist_ok=True) + case5reqs_dir = root_temp_dir / "case5" / "requirements" + case5packs_dir = case5reqs_dir / "packs" + case5packs_dir.mkdir(parents=True, exist_ok=True) + (case5packs_dir / "packA.txt").write_text("requests") + (case5packs_dir / "packB.txt").write_text("attrs") + + case5profiles_dir = case5reqs_dir / "profiles" + case5profiles_dir.mkdir(parents=True, exist_ok=True) + profileAyml = """\ +packs: +- packA + +extras: +- ipykernel + """ + profileByml = """\ +packs: +- packB - fake_env = root_temp_dir / "case5" / "fake_env" - fake_env.mkdir(parents=True, exist_ok=True) - (case5req_dir / "packA.txt").write_text("requests") - (case5req_dir / "packB.txt").write_text("attrs") +extras: +- notebook + """ + (case5profiles_dir / "profileA.yml").write_text(profileAyml) + (case5profiles_dir / "profileB.yml").write_text(profileByml) yield root_temp_dir diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index a870479..1a87737 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -346,8 +346,8 @@ def test_copy_examples_force(example_cases, expected_paths, force): install_params = [ - ( # input: install requirements for packA - # expected: print_info output showing packA installed but not packB + ( # input: packs to install + # expected: output showing packA installed but not packB ("packA",), """Installed Packs: ---------------- diff --git a/tests/test_profilesmanager.py b/tests/test_profilesmanager.py new file mode 100644 index 0000000..51bd328 --- /dev/null +++ b/tests/test_profilesmanager.py @@ -0,0 +1,47 @@ +import pytest +import yaml + +from diffpy.cmi.profilesmanager import ProfilesManager + +install_params = [ + ( # input: profiles to install + # expected: print_profile output showing profileA + # installed but not profileB + ("profileA",), + """Installed Profiles: +------------------- + profileA + +Available Profiles: +------------------- + profileB +""", + ), +] + + +@pytest.mark.parametrize("profiles_to_install,expected", install_params) +def test_print_profiles( + profiles_to_install, expected, example_cases, capsys, mocker +): + case5dir = example_cases / "case5" + req_dir = case5dir / "requirements" / "profiles" + + installed_reqs = [] + for profile in profiles_to_install: + req_file = req_dir / f"{profile}.yml" + content = yaml.safe_load(req_file.read_text()) + for pack in content.get("packs", []): + installed_reqs.append(pack) + + def fake_check_profile(identifier): + return identifier == "profileA" + + mocker.patch.object( + ProfilesManager, "check_profile", side_effect=fake_check_profile + ) + pfm = ProfilesManager(root_path=case5dir) + pfm.print_profiles() + captured = capsys.readouterr() + actual = captured.out + assert actual.strip() == expected.strip()