From 54974bae2e7cc50aa2e0340031b2fb5e7cf451cc Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 15:24:55 -0400 Subject: [PATCH 01/32] initial listing functions for cli --- src/diffpy/cmi/__init__.py | 14 +++++++++++++- src/diffpy/cmi/packsmanager.py | 9 +++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/diffpy/cmi/__init__.py b/src/diffpy/cmi/__init__.py index 62108fd..a92b2bb 100644 --- a/src/diffpy/cmi/__init__.py +++ b/src/diffpy/cmi/__init__.py @@ -18,7 +18,19 @@ from importlib.resources import as_file, files -def get_package_dir(): +def get_package_dir(root_path=None): + """Get the package directory as a context manager. + + Parameters + ---------- + root_path : str, optional + Used for testing, overrides the files(__name__) call. + + Returns + ------- + context manager + A context manager that yields a pathlib.Path to the package directory. + """ resource = files(__name__) return as_file(resource) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index bd8b10b..9467072 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -68,6 +68,15 @@ def available_packs(self) -> List[str]: p.stem for p in self.packs_dir.glob("*.txt") if p.is_file() ) + def available_examples(self): + """Finds all examples for each pack and builds a dict.""" + return + + def print_info(self): + """Pretty print available and installed packs and examples to + console.""" + return + def _resolve_pack_file(self, identifier: Union[str, Path]) -> Path: """Resolve a pack identifier to an absolute .txt path. From c9cf238872aaf593409adbf874278ad97de69f4d Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 15:31:07 -0400 Subject: [PATCH 02/32] initial tests --- tests/test__init__.py | 11 +++++++++++ tests/test_packsmanager.py | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/test__init__.py create mode 100644 tests/test_packsmanager.py diff --git a/tests/test__init__.py b/tests/test__init__.py new file mode 100644 index 0000000..f75aabd --- /dev/null +++ b/tests/test__init__.py @@ -0,0 +1,11 @@ +# from diffpy.cmi import get_package_dir +from pathlib import Path + +import pytest + + +@pytest.mark.parametrize("root_path", [None, str(Path(__file__).parent)]) +def test_get_package_dir(root_path): + """Test that get_package_dir returns a valid path context + manager.""" + assert False diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py new file mode 100644 index 0000000..0f166e1 --- /dev/null +++ b/tests/test_packsmanager.py @@ -0,0 +1,11 @@ +# from diffpy.cmi.packsmanager import PacksManager + + +def test_available_examples(): + """Test that available_examples returns a dict.""" + assert False + + +def test_print_info(): + """Test that print_info runs without error.""" + assert False From f9a14c30b8ed80dcdcf907e26fd05b460ec65bd5 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 16:13:36 -0400 Subject: [PATCH 03/32] test for listing available examples --- tests/test_packsmanager.py | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 0f166e1..646fa66 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -1,9 +1,35 @@ -# from diffpy.cmi.packsmanager import PacksManager +import pytest +from diffpy.cmi.packsmanager import PacksManager -def test_available_examples(): + +@pytest.mark.parametrize( + "expected_dict", + [ + { + "pdf": [ + "ch03NiModelling", + "ch06RefineCrystalStructureGen", + "ch07StructuralPhaseTransition", + "ch08NPRefinement", + ] + } + ], +) +def test_available_examples(expected_dict): """Test that available_examples returns a dict.""" - assert False + pkmg = PacksManager() + returned_dict = pkmg.available_examples() + expected_pack = list(expected_dict.keys()) + returned_pack = list(returned_dict.keys()) + for pack in expected_pack: + assert pack in returned_pack, f"{pack} not found in returned packs." + expected_examples = expected_dict[pack] + returned_examples = returned_dict.get(pack, []) + for ex in expected_examples: + assert ( + ex in returned_examples + ), f"{ex} not found under pack {pack}." def test_print_info(): From 71423d5d710aa423b6f5fd5fbd207c7d270ee5fd Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 17:01:36 -0400 Subject: [PATCH 04/32] test pretty print --- tests/test_packsmanager.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 646fa66..dc406e8 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -32,6 +32,10 @@ def test_available_examples(expected_dict): ), f"{ex} not found under pack {pack}." -def test_print_info(): - """Test that print_info runs without error.""" - assert False +def test_print_info(capsys): + """Test that print_info prints expected information to stdout.""" + pkmg = PacksManager() + pkmg.print_info() + captured = capsys.readouterr() + output = captured.out.strip() + assert "Available packs" in output or "Installed packs" in output From a1ee907909fd7cb07697169490cb4228ccf4127f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 18:29:36 -0400 Subject: [PATCH 05/32] api for copying packs and examples --- src/diffpy/cmi/cli.py | 72 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/src/diffpy/cmi/cli.py b/src/diffpy/cmi/cli.py index f25cb78..64cf086 100644 --- a/src/diffpy/cmi/cli.py +++ b/src/diffpy/cmi/cli.py @@ -26,7 +26,7 @@ # Examples -def _get_examples_dir() -> Path: +def _get_examples_dir(root_path=None) -> Path: """Return the absolute path to the installed examples directory. Returns @@ -39,7 +39,7 @@ def _get_examples_dir() -> Path: FileNotFoundError If the examples directory cannot be located in the installation. """ - with get_package_dir() as pkgdir: + with get_package_dir(root_path) as pkgdir: pkg = Path(pkgdir).resolve() for c in ( pkg / "docs" / "examples", @@ -72,6 +72,74 @@ def map_pack_to_examples() -> dict[str, List[str]]: return examples_by_pack +def copy_examples( + examples: str | List[str], + target_dir: Optional[Path] = None, +) -> List[Path]: + """Copy one or more examples to a target directory. + + Parameters + ---------- + examples : str or list of str + Example name(s): 'example1' or ['example1', 'example2'] + target_dir : Path, optional + Target directory where examples should be copied. + Defaults to current working directory if not specified. + overwrite : bool, default False + If True, overwrite existing directories. If False, raise + FileExistsError when destination exists. + + Returns + ------- + list of Path + List of destination paths created. + + Raises + ------ + ValueError + If example name is ambiguous (exists in multiple packs). + FileNotFoundError + If example does not exist. + FileExistsError + If destination exists and overwrite=False. + """ + return + + +def copy_packs( + packs: str | List[str], + target_dir: Optional[Path] = None, +) -> List[Path]: + """Copy all examples from one or more packs to a target directory. + + Parameters + ---------- + packs : str or list of str + Pack name(s). Can be: + - Single pack name: 'pack1' + - List of pack names: ['pack1', 'pack2'] + - Special keyword: 'all' (copies all packs) + target_dir : Path, optional + Target directory where examples should be copied. + Defaults to current working directory if not specified. + + Returns + ------- + list of Path + List of destination paths created (all examples from the pack(s)). + + Raises + ------ + ValueError + If pack name is invalid. + FileNotFoundError + If pack does not exist. + FileExistsError + If any destination exists. + """ + return + + def copy_example(pack_example: str) -> Path: """Copy an example into the current working directory. From b16c90b0190f1c5f0f77cbffb189437b00660172 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 22:08:06 -0400 Subject: [PATCH 06/32] have one function for copying examples --- src/diffpy/cmi/cli.py | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/src/diffpy/cmi/cli.py b/src/diffpy/cmi/cli.py index 64cf086..e627f14 100644 --- a/src/diffpy/cmi/cli.py +++ b/src/diffpy/cmi/cli.py @@ -73,21 +73,18 @@ def map_pack_to_examples() -> dict[str, List[str]]: def copy_examples( - examples: str | List[str], + examples: List[str], target_dir: Optional[Path] = None, ) -> List[Path]: """Copy one or more examples to a target directory. Parameters ---------- - examples : str or list of str - Example name(s): 'example1' or ['example1', 'example2'] + examples : list of str + Example name(s): ['example1'], ['pack1'] target_dir : Path, optional Target directory where examples should be copied. Defaults to current working directory if not specified. - overwrite : bool, default False - If True, overwrite existing directories. If False, raise - FileExistsError when destination exists. Returns ------- @@ -106,40 +103,6 @@ def copy_examples( return -def copy_packs( - packs: str | List[str], - target_dir: Optional[Path] = None, -) -> List[Path]: - """Copy all examples from one or more packs to a target directory. - - Parameters - ---------- - packs : str or list of str - Pack name(s). Can be: - - Single pack name: 'pack1' - - List of pack names: ['pack1', 'pack2'] - - Special keyword: 'all' (copies all packs) - target_dir : Path, optional - Target directory where examples should be copied. - Defaults to current working directory if not specified. - - Returns - ------- - list of Path - List of destination paths created (all examples from the pack(s)). - - Raises - ------ - ValueError - If pack name is invalid. - FileNotFoundError - If pack does not exist. - FileExistsError - If any destination exists. - """ - return - - def copy_example(pack_example: str) -> Path: """Copy an example into the current working directory. From 15c81118ed81c71e78c4750080f60ed6e913bc10 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 22:35:01 -0400 Subject: [PATCH 07/32] move print_info to cli, add params to docstring in available_examples --- src/diffpy/cmi/cli.py | 8 +++++++- src/diffpy/cmi/packsmanager.py | 17 +++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/diffpy/cmi/cli.py b/src/diffpy/cmi/cli.py index e627f14..88bf448 100644 --- a/src/diffpy/cmi/cli.py +++ b/src/diffpy/cmi/cli.py @@ -39,7 +39,7 @@ def _get_examples_dir(root_path=None) -> Path: FileNotFoundError If the examples directory cannot be located in the installation. """ - with get_package_dir(root_path) as pkgdir: + with get_package_dir() as pkgdir: pkg = Path(pkgdir).resolve() for c in ( pkg / "docs" / "examples", @@ -103,6 +103,12 @@ def copy_examples( return +def print_info(pack_examples_dict): + """Pretty print available and installed packs and examples to + console.""" + return + + def copy_example(pack_example: str) -> Path: """Copy an example into the current working directory. diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index 9467072..8599fa6 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -68,13 +68,18 @@ def available_packs(self) -> List[str]: p.stem for p in self.packs_dir.glob("*.txt") if p.is_file() ) - def available_examples(self): - """Finds all examples for each pack and builds a dict.""" - return + def available_examples(self, root_path): + """Finds all examples for each pack and builds a dict. - def print_info(self): - """Pretty print available and installed packs and examples to - console.""" + Parameters + ---------- + root_path : Path + Root path to the examples directory. + Returns + ------- + dict + A dictionary mapping pack names to lists of example names. + """ return def _resolve_pack_file(self, identifier: Union[str, Path]) -> Path: From db2ac9a94fa68a5fc04766333cdddb8790e076eb Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 23:25:22 -0400 Subject: [PATCH 08/32] add fnferror to api --- src/diffpy/cmi/packsmanager.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index 8599fa6..024c841 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -79,6 +79,11 @@ def available_examples(self, root_path): ------- dict A dictionary mapping pack names to lists of example names. + + Raises + ------ + FileNotFoundError + If the provided root_path does not exist or is not a directory. """ return From 9fcef71776b4f39be843d9537e63e59b329680bc Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 6 Oct 2025 23:30:40 -0400 Subject: [PATCH 09/32] update available_examples test --- tests/test_packsmanager.py | 54 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index dc406e8..47b4550 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -4,37 +4,43 @@ @pytest.mark.parametrize( - "expected_dict", + "expected", [ { - "pdf": [ - "ch03NiModelling", - "ch06RefineCrystalStructureGen", - "ch07StructuralPhaseTransition", - "ch08NPRefinement", + # test with pack that has examples + "pack1": [ + "ex1", + "ex2", + "ex3", ] - } + }, + { + # test pack with no examples + "no_examples": [] + }, ], ) -def test_available_examples(expected_dict): - """Test that available_examples returns a dict.""" - pkmg = PacksManager() - returned_dict = pkmg.available_examples() - expected_pack = list(expected_dict.keys()) - returned_pack = list(returned_dict.keys()) - for pack in expected_pack: - assert pack in returned_pack, f"{pack} not found in returned packs." - expected_examples = expected_dict[pack] - returned_examples = returned_dict.get(pack, []) - for ex in expected_examples: - assert ( - ex in returned_examples - ), f"{ex} not found under pack {pack}." +def test_available_examples(temp_path, expected): + for pack, examples in expected.items(): + pack_dir = temp_path / pack + pack_dir.mkdir(parents=True, exist_ok=True) + for ex in examples: + ex_dir = pack_dir / ex + ex_dir.mkdir(parents=True, exist_ok=True) + pkmg = PacksManager(temp_path) + actual = pkmg.available_examples(temp_path) + assert actual == expected + + +def test_available_examples_bad(temp_path): + pkmg = PacksManager(temp_path) + bad_path = temp_path / "nonexistent" + with pytest.raises(FileNotFoundError): + pkmg.available_examples(bad_path) -def test_print_info(capsys): - """Test that print_info prints expected information to stdout.""" - pkmg = PacksManager() +def test_print_info(temp_path, capsys): + pkmg = PacksManager(temp_path) pkmg.print_info() captured = capsys.readouterr() output = captured.out.strip() From c70ca27031f1f635b85bc4faf46e84f75e715132 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 7 Oct 2025 13:34:17 -0400 Subject: [PATCH 10/32] have pkmg methods take temp_path instead of pkmg --- tests/test_packsmanager.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 47b4550..36fd48e 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -4,20 +4,24 @@ @pytest.mark.parametrize( - "expected", + "input,expected", [ + # Pack with no examples + {"empty_pack": []}, + # Pack with multiple examples { - # test with pack that has examples - "pack1": [ - "ex1", - "ex2", - "ex3", + "full_pack": [ + ("example1", "path_to_1"), + ("example2", "path_to_2"), ] }, + # Multiple packs with examples { - # test pack with no examples - "no_examples": [] + "pack1": [("ex1", "path1"), ("ex2", "path2")], + "pack2": [("ex3", "path3")], }, + # No pack found + {}, ], ) def test_available_examples(temp_path, expected): @@ -27,21 +31,22 @@ def test_available_examples(temp_path, expected): for ex in examples: ex_dir = pack_dir / ex ex_dir.mkdir(parents=True, exist_ok=True) - pkmg = PacksManager(temp_path) + pkmg = PacksManager() actual = pkmg.available_examples(temp_path) assert actual == expected def test_available_examples_bad(temp_path): - pkmg = PacksManager(temp_path) + pkmg = PacksManager() bad_path = temp_path / "nonexistent" with pytest.raises(FileNotFoundError): pkmg.available_examples(bad_path) def test_print_info(temp_path, capsys): - pkmg = PacksManager(temp_path) - pkmg.print_info() + pkmg = PacksManager() + actual = pkmg.available_examples(temp_path) + pkmg.print_info(actual) captured = capsys.readouterr() output = captured.out.strip() assert "Available packs" in output or "Installed packs" in output From d32201a7e5e66f00bb91046ceee3ef4f8032dbb4 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 7 Oct 2025 14:03:08 -0400 Subject: [PATCH 11/32] test print info and test copy examples --- tests/test_cli.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index 9eb9712..635e787 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,6 +4,24 @@ import pytest from diffpy.cmi import cli +from diffpy.cmi.packsmanager import PacksManager + + +def test_print_info(temp_path, capsys): + pkmg = PacksManager() + actual = pkmg.available_examples(temp_path) + # pretty print the actual dict + pkmg.print_info(actual) + captured = capsys.readouterr() + output = captured.out.strip() + # check that output contains expected headers + assert "Available packs" in output or "Installed packs" in output + + +@pytest.mark.parametrize() +def test_copy_examples(dict, tmp_path): + cli.copy_examples(examples=dict, target_dir=tmp_path) + assert False def test_map_pack_to_examples_structure(): From fbbf88c0b0f7f0eb54905855ec7425cccf6c0c88 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 7 Oct 2025 17:15:45 -0400 Subject: [PATCH 12/32] checkpoint1 commit of working available examples tests --- tests/test_packsmanager.py | 87 ++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 36fd48e..4d7f30d 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -4,49 +4,54 @@ @pytest.mark.parametrize( + # 1) pack with no examples. Expect {'empty_pack': []} + # 2) pack with multiple examples. + # Expect {'full_pack': [('example1`, path_to_1'), 'example2', path_to_2)] + # 3) multiple packs. Expect dict with multiple pack:tuple pairs + # 4) no pack found. Expect {} "input,expected", [ - # Pack with no examples - {"empty_pack": []}, - # Pack with multiple examples - { - "full_pack": [ - ("example1", "path_to_1"), - ("example2", "path_to_2"), - ] - }, - # Multiple packs with examples - { - "pack1": [("ex1", "path1"), ("ex2", "path2")], - "pack2": [("ex3", "path3")], - }, - # No pack found - {}, + # case 1: pack with no examples. Expect {'empty_pack': []} + ( + "case1", + {"empty_pack": []}, + ), + # case 2: pack with multiple examples. + # Expect {'full_pack': [('example1', path_to_1), + # ('example2', path_to_2)]} + ( + "case2", + { + "full_pack": [ + ("example1", "path_to_1"), + ("example2", "path_to_2"), + ] + }, + ) + # case 3: multiple packs. Expect dict with multiple pack:tuple pairs + ( + "case3", + { + "pack1": [("ex1", "path1"), ("ex2", "path2")], + "pack2": [("ex3", "path3")], + }, + ), + # ( # case 4: no pack found. Expect {} + # None, + # {}, + # ) ], ) -def test_available_examples(temp_path, expected): - for pack, examples in expected.items(): - pack_dir = temp_path / pack - pack_dir.mkdir(parents=True, exist_ok=True) - for ex in examples: - ex_dir = pack_dir / ex - ex_dir.mkdir(parents=True, exist_ok=True) - pkmg = PacksManager() - actual = pkmg.available_examples(temp_path) +def test_available_examples(input, expected, example_cases): + test_path = (example_cases / input / "requirements" / "packs").resolve() + # print("examples:", test_path) + for path in test_path.rglob("*"): + # print(" -", path.relative_to(example_cases)) + if path.suffix: + assert path.is_file(), f"{path} should be a file" + else: + assert path.is_dir(), f"{path} should be a directory" + pkmg = PacksManager(test_path) + # print(pkmg.examples_dir) + actual = pkmg.available_examples() assert actual == expected - - -def test_available_examples_bad(temp_path): - pkmg = PacksManager() - bad_path = temp_path / "nonexistent" - with pytest.raises(FileNotFoundError): - pkmg.available_examples(bad_path) - - -def test_print_info(temp_path, capsys): - pkmg = PacksManager() - actual = pkmg.available_examples(temp_path) - pkmg.print_info(actual) - captured = capsys.readouterr() - output = captured.out.strip() - assert "Available packs" in output or "Installed packs" in output From a458c5eed4b5d9a532440548f55b067e80f349b1 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 7 Oct 2025 17:22:12 -0400 Subject: [PATCH 13/32] checkpoint conftest, build example_cases fixture --- tests/conftest.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 3eaae7d..7cde855 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,6 +22,65 @@ def tmp_examples(tmp_path_factory): yield tmp_examples +def _build_example_structure(base_dir: Path): + """Helper to build a fake examples directory structure for + testing.""" + packs = ["packA", "packB"] + examples_per_pack = ["example1", "example2"] + + for pack in packs: + for example in examples_per_pack: + example_path = base_dir / pack / example + example_path.mkdir(parents=True, exist_ok=True) + (example_path / "script.py").touch() + + +@pytest.fixture(scope="session") +def example_cases(tmp_path_factory): + """Copy the entire examples/ tree into a temp directory once per + test session. + + Returns the path to that copy. + """ + examples_dir = tmp_path_factory.mktemp("examples") + # case 1: pack with no examples + case1 = examples_dir / "case1" / "examples" / "empty_pack" + case1.mkdir(parents=True, exist_ok=True) + + # Case 2: pack with multiple examples + case2_paths_and_files = [ + ("case2/examples/full_pack/ex1/solutions/diffpy-cmi", "script1.py"), + ("case2/examples/full_pack/ex2/random/dir/path", "script2.py"), + ] + for dir_path, file_name in case2_paths_and_files: + full_path = examples_dir / dir_path + full_path.mkdir(parents=True, exist_ok=True) + (full_path / file_name).touch() + + # Case 3: multiple packs with multiple examples + case3_paths_and_files = [ + ("case3/examples/pack1/ex1/", "script1.py"), + ("case3/examples/pack2/ex1/", "script1.py"), + ] + for dir_path, file_name in case3_paths_and_files: + full_path = examples_dir / dir_path + full_path.mkdir(parents=True, exist_ok=True) + (full_path / file_name).touch() + + base_case3 = examples_dir / "case3" / "examples" + packs = ["packA", "packB"] + examples_per_pack = ["example1", "example2"] + + for pack in packs: + for example in examples_per_pack: + example_path = base_case3 / pack / example + example_path.mkdir(parents=True, exist_ok=True) + (example_path / "script.py").touch() + # tmp_examples = tmpdir / "case3" / "examples" + # tmp_examples = tmpdir / "case4" / "examples" + yield examples_dir + + @pytest.fixture(scope="session", autouse=True) def use_headless_matplotlib(): """Force matplotlib to use a headless backend during tests.""" From 736b519cac33333a15845e361be1683cad0d8b77 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 09:58:15 -0400 Subject: [PATCH 14/32] checkpoint packsmanager.py file --- src/diffpy/cmi/packsmanager.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index 024c841..8f80f6e 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -28,7 +28,7 @@ __all__ = ["PacksManager"] -def _installed_packs_dir() -> Path: +def _installed_packs_dir(root_path=None) -> Path: """Locate requirements/packs/ for the installed package.""" with get_package_dir() as pkgdir: pkg = Path(pkgdir).resolve() @@ -53,8 +53,27 @@ class PacksManager: Defaults to `requirements/packs` under the installed package. """ - def __init__(self) -> None: - self.packs_dir = _installed_packs_dir() + def __init__(self, root_path=None) -> None: + if root_path is None: + self.packs_dir = _installed_packs_dir(root_path) + else: + self.packs_dir = Path(root_path).resolve() + self.examples_dir = self._get_examples_dir() + + def _get_examples_dir(self) -> Path: + """Return the absolute path to the installed examples directory. + + Returns + ------- + pathlib.Path + Directory containing shipped examples. + + Raises + ------ + FileNotFoundError + If the examples directory cannot be located in the installation. + """ + return (self.packs_dir / ".." / ".." / "docs" / "examples").resolve() def available_packs(self) -> List[str]: """List all available packs. From 0bd26fcfae118d53ab2f7100205f60f1a78c5268 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 10:29:04 -0400 Subject: [PATCH 15/32] checkpoint: conftest is building correctly --- tests/conftest.py | 71 +++++++++++++++++--------------------- tests/test_packsmanager.py | 47 +++++++++++++------------ 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 7cde855..aee0e56 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,17 +22,31 @@ def tmp_examples(tmp_path_factory): yield tmp_examples -def _build_example_structure(base_dir: Path): - """Helper to build a fake examples directory structure for - testing.""" - packs = ["packA", "packB"] - examples_per_pack = ["example1", "example2"] - - for pack in packs: - for example in examples_per_pack: - example_path = base_dir / pack / example - example_path.mkdir(parents=True, exist_ok=True) - (example_path / "script.py").touch() +def _build_examples_tree_helper( + base_dir: Path, structure: dict[str, dict[str, list[tuple[str, str]]]] +): + """Build a nested examples directory structure based on a mapping. + + Parameters + ---------- + base_dir : Path + The root temporary directory (e.g., from tmp_path_factory). + structure : dict + Mapping of case -> {pack: [(example_name, relative_script_path), ...]}. + """ + for case_name, packs in structure.items(): + for pack_name, examples in packs.items(): + for example_name, script_relpath in examples: + script_path = ( + base_dir + / case_name + / pack_name + / example_name + / Path(script_relpath) + ) + script_path.parent.mkdir(parents=True, exist_ok=True) + script_path.touch() + return base_dir @pytest.fixture(scope="session") @@ -43,39 +57,16 @@ def example_cases(tmp_path_factory): Returns the path to that copy. """ examples_dir = tmp_path_factory.mktemp("examples") + # case 1: pack with no examples - case1 = examples_dir / "case1" / "examples" / "empty_pack" + # case1_dict = {"case1": {"empty_pack": []}} + # _build_examples_tree_helper(examples_dir, case1_dict) + case1 = examples_dir / "case1" / "empty_pack" case1.mkdir(parents=True, exist_ok=True) - - # Case 2: pack with multiple examples - case2_paths_and_files = [ - ("case2/examples/full_pack/ex1/solutions/diffpy-cmi", "script1.py"), - ("case2/examples/full_pack/ex2/random/dir/path", "script2.py"), - ] - for dir_path, file_name in case2_paths_and_files: - full_path = examples_dir / dir_path - full_path.mkdir(parents=True, exist_ok=True) - (full_path / file_name).touch() + # # Case 2: pack with multiple examples # Case 3: multiple packs with multiple examples - case3_paths_and_files = [ - ("case3/examples/pack1/ex1/", "script1.py"), - ("case3/examples/pack2/ex1/", "script1.py"), - ] - for dir_path, file_name in case3_paths_and_files: - full_path = examples_dir / dir_path - full_path.mkdir(parents=True, exist_ok=True) - (full_path / file_name).touch() - - base_case3 = examples_dir / "case3" / "examples" - packs = ["packA", "packB"] - examples_per_pack = ["example1", "example2"] - - for pack in packs: - for example in examples_per_pack: - example_path = base_case3 / pack / example - example_path.mkdir(parents=True, exist_ok=True) - (example_path / "script.py").touch() + # tmp_examples = tmpdir / "case3" / "examples" # tmp_examples = tmpdir / "case4" / "examples" yield examples_dir diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 4d7f30d..981d6e5 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -19,23 +19,23 @@ # case 2: pack with multiple examples. # Expect {'full_pack': [('example1', path_to_1), # ('example2', path_to_2)]} - ( - "case2", - { - "full_pack": [ - ("example1", "path_to_1"), - ("example2", "path_to_2"), - ] - }, - ) - # case 3: multiple packs. Expect dict with multiple pack:tuple pairs - ( - "case3", - { - "pack1": [("ex1", "path1"), ("ex2", "path2")], - "pack2": [("ex3", "path3")], - }, - ), + # ( + # "case2", + # { + # "full_pack": [ + # ("example1", "path_to_1"), + # ("example2", "path_to_2"), + # ] + # }, + # ), + # # case 3: multiple packs. Expect dict with multiple pack:tuple pairs + # ( + # "case3", + # { + # "pack1": [("ex1", "path1"), ("ex2", "path2")], + # "pack2": [("ex3", "path3")], + # }, + # ), # ( # case 4: no pack found. Expect {} # None, # {}, @@ -43,15 +43,16 @@ ], ) def test_available_examples(input, expected, example_cases): - test_path = (example_cases / input / "requirements" / "packs").resolve() - # print("examples:", test_path) + test_path = example_cases / input + # print("test_path:", test_path) for path in test_path.rglob("*"): - # print(" -", path.relative_to(example_cases)) + print(" -", path.relative_to(example_cases)) if path.suffix: assert path.is_file(), f"{path} should be a file" else: assert path.is_dir(), f"{path} should be a directory" pkmg = PacksManager(test_path) - # print(pkmg.examples_dir) - actual = pkmg.available_examples() - assert actual == expected + # print(pkmg.packs_dir) + print(pkmg.examples_dir) + # actual = pkmg.available_examples() + # assert actual == expected From 4be38f68e68a39cfd497978f3bc97f007bd32ec6 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 13:26:56 -0400 Subject: [PATCH 16/32] checkpoint, working version that gets examples dir outside of PacksManager --- src/diffpy/cmi/packsmanager.py | 57 +++++++++++++++++++++++----------- tests/conftest.py | 27 +++++++++++++--- tests/test_packsmanager.py | 28 ++++++++++------- 3 files changed, 79 insertions(+), 33 deletions(-) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index 8f80f6e..f5bbc9b 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -43,6 +43,29 @@ def _installed_packs_dir(root_path=None) -> Path: ) +def _examples_dir(root_path=None) -> Path: + """Return the absolute path to the installed examples directory. + + Returns + ------- + pathlib.Path + Directory containing shipped examples. + + Raises + ------ + FileNotFoundError + If the examples directory cannot be located in the installation. + """ + with get_package_dir() as pkgdir: + pkg = Path(pkgdir).resolve() + for c in (pkg.parents[2] / "docs" / "examples",): + if c.is_dir(): + return c + raise FileNotFoundError( + "Could not locate docs/examples. Check your installation." + ) + + class PacksManager: """Discovery, parsing, and installation for pack files. @@ -56,24 +79,10 @@ class PacksManager: def __init__(self, root_path=None) -> None: if root_path is None: self.packs_dir = _installed_packs_dir(root_path) + self.examples_dir = _examples_dir(root_path) else: self.packs_dir = Path(root_path).resolve() - self.examples_dir = self._get_examples_dir() - - def _get_examples_dir(self) -> Path: - """Return the absolute path to the installed examples directory. - - Returns - ------- - pathlib.Path - Directory containing shipped examples. - - Raises - ------ - FileNotFoundError - If the examples directory cannot be located in the installation. - """ - return (self.packs_dir / ".." / ".." / "docs" / "examples").resolve() + self.examples_dir = Path(root_path).resolve() def available_packs(self) -> List[str]: """List all available packs. @@ -87,7 +96,7 @@ def available_packs(self) -> List[str]: p.stem for p in self.packs_dir.glob("*.txt") if p.is_file() ) - def available_examples(self, root_path): + def available_examples(self) -> dict[str, List[tuple[str, Path]]]: """Finds all examples for each pack and builds a dict. Parameters @@ -104,7 +113,19 @@ def available_examples(self, root_path): FileNotFoundError If the provided root_path does not exist or is not a directory. """ - return + example_dir = self.examples_dir + examples_dict = {} + for pack_path in example_dir.iterdir(): + if pack_path.is_dir(): + pack_name = pack_path.stem + examples_dict[pack_name] = [] + for example_path in pack_path.iterdir(): + if example_path.is_dir(): + example_name = example_path.stem + examples_dict[pack_name].append( + (example_name, example_path) + ) + return examples_dict def _resolve_pack_file(self, identifier: Union[str, Path]) -> Path: """Resolve a pack identifier to an absolute .txt path. diff --git a/tests/conftest.py b/tests/conftest.py index aee0e56..541d340 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -57,16 +57,35 @@ def example_cases(tmp_path_factory): Returns the path to that copy. """ examples_dir = tmp_path_factory.mktemp("examples") - # case 1: pack with no examples # case1_dict = {"case1": {"empty_pack": []}} # _build_examples_tree_helper(examples_dir, case1_dict) case1 = examples_dir / "case1" / "empty_pack" case1.mkdir(parents=True, exist_ok=True) - # # Case 2: pack with multiple examples - - # Case 3: multiple packs with multiple examples + # # Case 2: pack with multiple examples + case2a = ( + examples_dir + / "case2" + / "full_pack" + / "example1" + / "solution" + / "diffpy-cmi" + ) # full_pack, example1 + case2a.mkdir(parents=True, exist_ok=True) + (case2a / "script1.py").touch() + case2b = ( + examples_dir / "case2" / "full_pack" / "example2" / "random" / "path" + ) # full_pack, example2 + case2b.mkdir(parents=True, exist_ok=True) + (case2b / "script1.py").touch() + (case2b / "script2.py").touch() + + # # Case 3: multiple packs with multiple examples + # case3a = examples_dir / "case3" / "pack1" / "ex1" # pack1, ex1 + # case3a.mkdir(parents=True, exist_ok=True) + # (case3b / "script1.py").touch() + # case3b = examples_dir / # tmp_examples = tmpdir / "case3" / "examples" # tmp_examples = tmpdir / "case4" / "examples" yield examples_dir diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 981d6e5..6258ba4 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -19,15 +19,15 @@ # case 2: pack with multiple examples. # Expect {'full_pack': [('example1', path_to_1), # ('example2', path_to_2)]} - # ( - # "case2", - # { - # "full_pack": [ - # ("example1", "path_to_1"), - # ("example2", "path_to_2"), - # ] - # }, - # ), + ( + "case2", + { + "full_pack": [ + ("example1", ["full_pack", "example1"]), + ("example2", ["full_pack", "example2"]), + ] + }, + ), # # case 3: multiple packs. Expect dict with multiple pack:tuple pairs # ( # "case3", @@ -52,7 +52,13 @@ def test_available_examples(input, expected, example_cases): else: assert path.is_dir(), f"{path} should be a directory" pkmg = PacksManager(test_path) - # print(pkmg.packs_dir) - print(pkmg.examples_dir) + assert pkmg.examples_dir == test_path + print("packs_dir:", pkmg.packs_dir) + print("examples_dir:", pkmg.examples_dir) + for path in pkmg.examples_dir.rglob("*"): + print(" +", path.relative_to(pkmg.examples_dir.parent)) + # actual = pkmg.available_examples() + # assert that the keys are the same + # assert actual.keys() == expected.keys() # assert actual == expected From 280390ce47973171c45d7739ce2bb05a83fd17f3 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 14:21:34 -0400 Subject: [PATCH 17/32] checkpoint: _get_examples_dir moved back in PacksManager and paths are being found. the keys of actual and expected are asserting True --- src/diffpy/cmi/packsmanager.py | 44 ++++++++++++++++------------------ tests/test_packsmanager.py | 34 ++++++++++++++++---------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index f5bbc9b..582ca1f 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -43,29 +43,6 @@ def _installed_packs_dir(root_path=None) -> Path: ) -def _examples_dir(root_path=None) -> Path: - """Return the absolute path to the installed examples directory. - - Returns - ------- - pathlib.Path - Directory containing shipped examples. - - Raises - ------ - FileNotFoundError - If the examples directory cannot be located in the installation. - """ - with get_package_dir() as pkgdir: - pkg = Path(pkgdir).resolve() - for c in (pkg.parents[2] / "docs" / "examples",): - if c.is_dir(): - return c - raise FileNotFoundError( - "Could not locate docs/examples. Check your installation." - ) - - class PacksManager: """Discovery, parsing, and installation for pack files. @@ -74,16 +51,35 @@ class PacksManager: packs_dir : pathlib.Path Absolute path to the installed packs directory. Defaults to `requirements/packs` under the installed package. + examples_dir : pathlib.Path + Absolute path to the installed examples directory. + Defaults to `docs/examples` under the installed package. """ def __init__(self, root_path=None) -> None: if root_path is None: self.packs_dir = _installed_packs_dir(root_path) - self.examples_dir = _examples_dir(root_path) + self.examples_dir = self._get_examples_dir() + # root_path option provided for testing else: self.packs_dir = Path(root_path).resolve() self.examples_dir = Path(root_path).resolve() + def _get_examples_dir(self) -> Path: + """Return the absolute path to the installed examples directory. + + Returns + ------- + pathlib.Path + Directory containing shipped examples. + + Raises + ------ + FileNotFoundError + If the examples directory cannot be located in the installation. + """ + return (self.packs_dir / ".." / ".." / "docs" / "examples").resolve() + def available_packs(self) -> List[str]: """List all available packs. diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 6258ba4..ecd2ff5 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -1,3 +1,5 @@ +from pprint import pprint + import pytest from diffpy.cmi.packsmanager import PacksManager @@ -23,8 +25,8 @@ "case2", { "full_pack": [ - ("example1", ["full_pack", "example1"]), - ("example2", ["full_pack", "example2"]), + ("example1", "case2/full_pack/example1"), + ("example2", "case2/full_pack/example2"), ] }, ), @@ -43,22 +45,28 @@ ], ) def test_available_examples(input, expected, example_cases): - test_path = example_cases / input + root_path = example_cases / input # print("test_path:", test_path) - for path in test_path.rglob("*"): - print(" -", path.relative_to(example_cases)) + pkmg = PacksManager(root_path) + print() + # print("packsmananger_dir:", pkmg.examples_dir) + # print("conftest_dir:", root_path) + for path in root_path.rglob("*"): + # print(" -", path.relative_to(example_cases)) if path.suffix: assert path.is_file(), f"{path} should be a file" else: assert path.is_dir(), f"{path} should be a directory" - pkmg = PacksManager(test_path) - assert pkmg.examples_dir == test_path - print("packs_dir:", pkmg.packs_dir) - print("examples_dir:", pkmg.examples_dir) - for path in pkmg.examples_dir.rglob("*"): - print(" +", path.relative_to(pkmg.examples_dir.parent)) + assert pkmg.examples_dir == root_path + # for path in pkmg.examples_dir.rglob("*"): + # print(" +", path.relative_to(pkmg.examples_dir.parent)) - # actual = pkmg.available_examples() + actual = pkmg.available_examples() + print("expected:") + pprint(expected) + print("actual:") + pprint(actual) # assert that the keys are the same - # assert actual.keys() == expected.keys() + assert actual.keys() == expected.keys() + # if values of excepted are in actual assert true # assert actual == expected From 99c4951de4849cb99ead5acfc3a069257c30ab45 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 14:25:34 -0400 Subject: [PATCH 18/32] forgot to add conftest to previous checkpoint commit, so its added in this commit --- tests/conftest.py | 3 ++- tests/test_packsmanager.py | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 541d340..d870205 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -57,13 +57,14 @@ def example_cases(tmp_path_factory): Returns the path to that copy. """ examples_dir = tmp_path_factory.mktemp("examples") + # case 1: pack with no examples # case1_dict = {"case1": {"empty_pack": []}} # _build_examples_tree_helper(examples_dir, case1_dict) case1 = examples_dir / "case1" / "empty_pack" case1.mkdir(parents=True, exist_ok=True) - # # Case 2: pack with multiple examples + # Case 2: pack with multiple examples case2a = ( examples_dir / "case2" diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index ecd2ff5..575756f 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -46,11 +46,10 @@ ) def test_available_examples(input, expected, example_cases): root_path = example_cases / input - # print("test_path:", test_path) pkmg = PacksManager(root_path) print() # print("packsmananger_dir:", pkmg.examples_dir) - # print("conftest_dir:", root_path) + # print("root_path:", root_path) for path in root_path.rglob("*"): # print(" -", path.relative_to(example_cases)) if path.suffix: From aa65d024f48ae217280596f01b271045b1a908dd Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 14:57:47 -0400 Subject: [PATCH 19/32] checkpoint: test that the path and examples match --- tests/test_packsmanager.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 575756f..e692ac2 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -66,6 +66,21 @@ def test_available_examples(input, expected, example_cases): print("actual:") pprint(actual) # assert that the keys are the same - assert actual.keys() == expected.keys() + + assert ( + actual.keys() == expected.keys() + ), f"Keys differ: expected {expected.keys()}, got {actual.keys()}" # if values of excepted are in actual assert true # assert actual == expected + for expected_pack, expected_tuple in expected.items(): + assert expected_pack in actual, f"Missing pack: {expected_pack}" + for expected_name, expected_rel_path in expected_tuple: + matches = [ + (name, path) + for name, path in actual[expected_pack] + if name == expected_name and expected_rel_path in str(path) + ] + assert matches, ( + f"Expected example '{expected_name}' with path containing " + f"'{expected_rel_path}' not found in {actual[expected_pack]}" + ) From 4aa15b0f10a28878cebb072ad27fa28e144cf26a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 8 Oct 2025 15:14:08 -0400 Subject: [PATCH 20/32] checkpoint: add all 4 cases to test_packsmanager --- tests/test_packsmanager.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index e692ac2..b23a1c4 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -30,18 +30,21 @@ ] }, ), - # # case 3: multiple packs. Expect dict with multiple pack:tuple pairs - # ( - # "case3", - # { - # "pack1": [("ex1", "path1"), ("ex2", "path2")], - # "pack2": [("ex3", "path3")], - # }, - # ), - # ( # case 4: no pack found. Expect {} - # None, - # {}, - # ) + # case 3: multiple packs. Expect dict with multiple pack:tuple pairs + ( + "case3", + { + "packA": [ + ("my_ex1", "case3/packA/my_ex1"), + ("my_ex2", "case3/packA/my_ex2"), + ], + "packB": [("my_ex1", "case3/packB/my_ex1")], + }, + ), + ( # case 4: no pack found. Expect {} + "case4", + {}, + ), ], ) def test_available_examples(input, expected, example_cases): @@ -51,7 +54,7 @@ def test_available_examples(input, expected, example_cases): # print("packsmananger_dir:", pkmg.examples_dir) # print("root_path:", root_path) for path in root_path.rglob("*"): - # print(" -", path.relative_to(example_cases)) + print(" -", path.relative_to(example_cases)) if path.suffix: assert path.is_file(), f"{path} should be a file" else: From cfb22737a63f3c39c5a7219015d43d305b0984b9 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 11:11:49 -0400 Subject: [PATCH 21/32] Add case 5, split into separate tests, and refactor code for style/readability --- tests/test_packsmanager.py | 150 ++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 76 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index b23a1c4..61e7031 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -1,89 +1,87 @@ -from pprint import pprint - import pytest from diffpy.cmi.packsmanager import PacksManager - -@pytest.mark.parametrize( +example_params = [ # 1) pack with no examples. Expect {'empty_pack': []} # 2) pack with multiple examples. # Expect {'full_pack': [('example1`, path_to_1'), 'example2', path_to_2)] # 3) multiple packs. Expect dict with multiple pack:tuple pairs # 4) no pack found. Expect {} - "input,expected", - [ - # case 1: pack with no examples. Expect {'empty_pack': []} - ( - "case1", - {"empty_pack": []}, - ), - # case 2: pack with multiple examples. - # Expect {'full_pack': [('example1', path_to_1), - # ('example2', path_to_2)]} - ( - "case2", - { - "full_pack": [ - ("example1", "case2/full_pack/example1"), - ("example2", "case2/full_pack/example2"), - ] - }, - ), - # case 3: multiple packs. Expect dict with multiple pack:tuple pairs - ( - "case3", - { - "packA": [ - ("my_ex1", "case3/packA/my_ex1"), - ("my_ex2", "case3/packA/my_ex2"), - ], - "packB": [("my_ex1", "case3/packB/my_ex1")], - }, - ), - ( # case 4: no pack found. Expect {} - "case4", - {}, - ), - ], -) + # case 1: pack with no examples. Expect {'empty_pack': []} + ( + "case1", + {"empty_pack": []}, + ), + # case 2: pack with multiple examples. + # Expect {'full_pack': [('example1', path_to_1), + # ('example2', path_to_2)]} + ( + "case2", + { + "full_pack": [ + ("example1", "case2/full_pack/example1"), + ("example2", "case2/full_pack/example2"), + ] + }, + ), + # case 3: multiple packs. Expect dict with multiple pack:tuple pairs + ( + "case3", + { + "packA": [ + ("my_ex1", "case3/packA/my_ex1"), + ("my_ex2", "case3/packA/my_ex2"), + ], + "packB": [("ex1", "case3/packB/ex1")], + }, + ), + ( # case 4: no pack found. Expect {} + "case4", + {}, + ), + ( # case 5: multiple packs with the same example names + # Expect dict with multiple pack:tuple pairs + "case5", + { + "packA": [ + ("example", "case5/packA/example"), + ], + "packB": [ + ("example", "case5/packB/example"), + ], + }, + ), +] + + +@pytest.mark.parametrize("input,expected", example_params) def test_available_examples(input, expected, example_cases): - root_path = example_cases / input - pkmg = PacksManager(root_path) - print() - # print("packsmananger_dir:", pkmg.examples_dir) - # print("root_path:", root_path) - for path in root_path.rglob("*"): - print(" -", path.relative_to(example_cases)) + tmp_ex_dir = example_cases / input + pkmg = PacksManager(tmp_ex_dir) + # Ensure the example directory is correctly set + assert pkmg.examples_dir == tmp_ex_dir + actual = pkmg.available_examples() + # Verify that the keys (pack names) are correct + assert set(actual.keys()) == set(expected.keys()) + # Verify that each expected example exists in actual + for expected_pack, expected_list in expected.items(): + actual_list = actual[expected_pack] + for (expected_exname, expected_path), ( + actual_exname, + actual_path, + ) in zip(expected_list, actual_list): + # Checks example name and path + assert expected_exname == actual_exname + assert expected_path == str(actual_path.relative_to(example_cases)) + + +@pytest.mark.parametrize("input,expected", example_params) +def test_tmp_(input, expected, example_cases): + example_path = example_cases / input + for path in example_path.rglob("*"): if path.suffix: - assert path.is_file(), f"{path} should be a file" + # Checks temp files are files and not dirs + assert path.is_file() else: assert path.is_dir(), f"{path} should be a directory" - assert pkmg.examples_dir == root_path - # for path in pkmg.examples_dir.rglob("*"): - # print(" +", path.relative_to(pkmg.examples_dir.parent)) - - actual = pkmg.available_examples() - print("expected:") - pprint(expected) - print("actual:") - pprint(actual) - # assert that the keys are the same - - assert ( - actual.keys() == expected.keys() - ), f"Keys differ: expected {expected.keys()}, got {actual.keys()}" - # if values of excepted are in actual assert true - # assert actual == expected - for expected_pack, expected_tuple in expected.items(): - assert expected_pack in actual, f"Missing pack: {expected_pack}" - for expected_name, expected_rel_path in expected_tuple: - matches = [ - (name, path) - for name, path in actual[expected_pack] - if name == expected_name and expected_rel_path in str(path) - ] - assert matches, ( - f"Expected example '{expected_name}' with path containing " - f"'{expected_rel_path}' not found in {actual[expected_pack]}" - ) From fdf09b2253b98487f7711f8da0149c481e923279 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 11:13:12 -0400 Subject: [PATCH 22/32] sort packs and examples when building dict with available_examples() --- src/diffpy/cmi/packsmanager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index 582ca1f..f1c3058 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -111,11 +111,11 @@ def available_examples(self) -> dict[str, List[tuple[str, Path]]]: """ example_dir = self.examples_dir examples_dict = {} - for pack_path in example_dir.iterdir(): + for pack_path in sorted(example_dir.iterdir()): if pack_path.is_dir(): pack_name = pack_path.stem examples_dict[pack_name] = [] - for example_path in pack_path.iterdir(): + for example_path in sorted(pack_path.iterdir()): if example_path.is_dir(): example_name = example_path.stem examples_dict[pack_name].append( From 53ac9a22b9021870dcf9b479593bd0a9824e6a26 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 11:15:38 -0400 Subject: [PATCH 23/32] add case 5 to conftest --- tests/conftest.py | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d870205..f5dca76 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -83,12 +83,33 @@ def example_cases(tmp_path_factory): (case2b / "script2.py").touch() # # Case 3: multiple packs with multiple examples - # case3a = examples_dir / "case3" / "pack1" / "ex1" # pack1, ex1 - # case3a.mkdir(parents=True, exist_ok=True) - # (case3b / "script1.py").touch() - # case3b = examples_dir / - # tmp_examples = tmpdir / "case3" / "examples" - # tmp_examples = tmpdir / "case4" / "examples" + case3a = examples_dir / "case3" / "packA" / "my_ex1" # packA, ex1 + case3a.mkdir(parents=True, exist_ok=True) + (case3a / "script1.py").touch() + case3b = ( + examples_dir / "case3" / "packA" / "my_ex2" / "solutions" + ) # packA, ex2 + case3b.mkdir(parents=True, exist_ok=True) + (case3b / "script2.py").touch() + case3c = ( + examples_dir / "case3" / "packB" / "ex1" / "more" / "random" / "path" + ) # packB, ex1 + case3c.mkdir(parents=True, exist_ok=True) + (case3c / "script3.py").touch() + (case3c / "script4.py").touch() + + # # Case 4: no pack found (empty directory) + case4 = examples_dir / "case4" + case4.mkdir(parents=True, exist_ok=True) + + # Case 5: multiple packs with the same example names + case5a = examples_dir / "case5" / "packA" / "example" / "path1" + case5a.mkdir(parents=True, exist_ok=True) + (case5a / "script1.py").touch() + case5b = examples_dir / "case5" / "packB" / "example" / "path2" + case5b.mkdir(parents=True, exist_ok=True) + (case5b / "script2.py").touch() + yield examples_dir From ce1efa74e8c421c8814434814a530c7a957a66bd Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 11:23:30 -0400 Subject: [PATCH 24/32] remove printed fail statement --- tests/test_packsmanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 61e7031..212f2c0 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -84,4 +84,4 @@ def test_tmp_(input, expected, example_cases): # Checks temp files are files and not dirs assert path.is_file() else: - assert path.is_dir(), f"{path} should be a directory" + assert path.is_dir() From c39dfae2d4e97e0cffe71e61dcf9180ae88cc59f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 11:45:09 -0400 Subject: [PATCH 25/32] rm unused helper function I made in conftest --- tests/conftest.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index f5dca76..9bdd482 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,33 +22,6 @@ def tmp_examples(tmp_path_factory): yield tmp_examples -def _build_examples_tree_helper( - base_dir: Path, structure: dict[str, dict[str, list[tuple[str, str]]]] -): - """Build a nested examples directory structure based on a mapping. - - Parameters - ---------- - base_dir : Path - The root temporary directory (e.g., from tmp_path_factory). - structure : dict - Mapping of case -> {pack: [(example_name, relative_script_path), ...]}. - """ - for case_name, packs in structure.items(): - for pack_name, examples in packs.items(): - for example_name, script_relpath in examples: - script_path = ( - base_dir - / case_name - / pack_name - / example_name - / Path(script_relpath) - ) - script_path.parent.mkdir(parents=True, exist_ok=True) - script_path.touch() - return base_dir - - @pytest.fixture(scope="session") def example_cases(tmp_path_factory): """Copy the entire examples/ tree into a temp directory once per @@ -113,6 +86,14 @@ def example_cases(tmp_path_factory): yield examples_dir +@pytest.fixture(scope="session") +def copy_target_dir(tmp_path_factory): + """Create a temporary directory to serve as the target for copying + examples.""" + target_dir = tmp_path_factory.mktemp("copy_target") + yield target_dir + + @pytest.fixture(scope="session", autouse=True) def use_headless_matplotlib(): """Force matplotlib to use a headless backend during tests.""" From c2e8076964277b564431fdac61a5a39db619d1c3 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 12:04:35 -0400 Subject: [PATCH 26/32] add comment for case5 ex --- tests/test_packsmanager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 212f2c0..335f0a5 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -9,6 +9,8 @@ # 3) multiple packs. Expect dict with multiple pack:tuple pairs # 4) no pack found. Expect {} # case 1: pack with no examples. Expect {'empty_pack': []} + # 5) multiple packs with the same example names + # Expect dict with multiple pack:tuple pairs ( "case1", {"empty_pack": []}, From d1038b768313ff14c5fe05b9336504239524bcd7 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 12:29:02 -0400 Subject: [PATCH 27/32] UCs for copy_examples tests --- tests/conftest.py | 6 +++--- tests/test_cli.py | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9bdd482..4746bcf 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -87,11 +87,11 @@ def example_cases(tmp_path_factory): @pytest.fixture(scope="session") -def copy_target_dir(tmp_path_factory): +def target_dir(tmp_path_factory): """Create a temporary directory to serve as the target for copying examples.""" - target_dir = tmp_path_factory.mktemp("copy_target") - yield target_dir + target_directory = tmp_path_factory.mktemp("copy_target") + yield target_directory @pytest.fixture(scope="session", autouse=True) diff --git a/tests/test_cli.py b/tests/test_cli.py index 635e787..884c9f5 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,5 +1,6 @@ import os from pathlib import Path +from shutil import copytree import pytest @@ -7,6 +8,41 @@ from diffpy.cmi.packsmanager import PacksManager +@pytest.mark.parametrize( + "input,to_cwd,expected", + [ + # PARAMS: + # input: list - list of example(s) and/or pack(s) to copy + # to_cwd: bool - whether to copy to cwd (default) or a target dir + # expected: list - path of copied example(s) and/or pack(s) + # 1a) user wants to copy one example to cwd + # 1b) user wants to copy one example to a target dir + (), + # 2a) user wants to copy multiple examples to cwd + # 2b) user wants to copy multiple examples to a target dir + (), + # 3a) user wants to copy all examples from a pack to cwd + # 3b) user wants to copy all examples from a pack to a target dir + (), + # 4a) user wants to copy all examples from multiple packs to cwd + # 4b) user wants to copy all examples from multiple packs to target dir + (), + # 5a) user wants to copy a combination of packs and examples to cwd + # 5b) user wants to copy a combination of packs and examples to target + (), + # 6a) user wants to copy all examples from all packs to cwd + # 6b) user wants to copy all examples from all packs to a target dir + (), + ], +) +def test_copy_examples(input, to_cwd, expected, example_cases, target_dir): + tmp_ex_dir = example_cases / input + copytree(tmp_ex_dir, target_dir) + # pkmg = PacksManager() + # actual = cli.copy_examples(str(target_dir)) + assert False + + def test_print_info(temp_path, capsys): pkmg = PacksManager() actual = pkmg.available_examples(temp_path) @@ -18,12 +54,7 @@ def test_print_info(temp_path, capsys): assert "Available packs" in output or "Installed packs" in output -@pytest.mark.parametrize() -def test_copy_examples(dict, tmp_path): - cli.copy_examples(examples=dict, target_dir=tmp_path) - assert False - - +# NOTE: double check and remove these test after new above tests are made def test_map_pack_to_examples_structure(): """Test that map_pack_to_examples returns the right shape of data.""" From 85bb7472f154107914cf563dd698b0f331d257f2 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 17:47:10 -0400 Subject: [PATCH 28/32] treat each 'caseX' as the root dir, build out from there --- src/diffpy/cmi/packsmanager.py | 11 ++----- tests/conftest.py | 60 +++++++++++++++++++--------------- tests/test_packsmanager.py | 52 +++++++++++++++-------------- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/src/diffpy/cmi/packsmanager.py b/src/diffpy/cmi/packsmanager.py index f1c3058..166ded5 100644 --- a/src/diffpy/cmi/packsmanager.py +++ b/src/diffpy/cmi/packsmanager.py @@ -30,7 +30,7 @@ def _installed_packs_dir(root_path=None) -> Path: """Locate requirements/packs/ for the installed package.""" - with get_package_dir() as pkgdir: + with get_package_dir(root_path) as pkgdir: pkg = Path(pkgdir).resolve() for c in ( pkg / "requirements" / "packs", @@ -57,13 +57,8 @@ class PacksManager: """ def __init__(self, root_path=None) -> None: - if root_path is None: - self.packs_dir = _installed_packs_dir(root_path) - self.examples_dir = self._get_examples_dir() - # root_path option provided for testing - else: - self.packs_dir = Path(root_path).resolve() - self.examples_dir = Path(root_path).resolve() + self.packs_dir = _installed_packs_dir(root_path) + self.examples_dir = self._get_examples_dir() def _get_examples_dir(self) -> Path: """Return the absolute path to the installed examples directory. diff --git a/tests/conftest.py b/tests/conftest.py index 4746bcf..ebcfad9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -24,66 +24,72 @@ def tmp_examples(tmp_path_factory): @pytest.fixture(scope="session") def example_cases(tmp_path_factory): - """Copy the entire examples/ tree into a temp directory once per - test session. + """Copy the entire examples tree into a temp directory once per test + session. Returns the path to that copy. """ - examples_dir = tmp_path_factory.mktemp("examples") + root_temp_dir = tmp_path_factory.mktemp("temp") # case 1: pack with no examples - # case1_dict = {"case1": {"empty_pack": []}} - # _build_examples_tree_helper(examples_dir, case1_dict) - case1 = examples_dir / "case1" / "empty_pack" + case1ex_dir = root_temp_dir / "case1" / "docs" / "examples" + case1 = case1ex_dir / "empty_pack" # empty_pack case1.mkdir(parents=True, exist_ok=True) + case1req_dir = root_temp_dir / "case1" / "requirements" / "packs" + case1req_dir.mkdir(parents=True, exist_ok=True) # Case 2: pack with multiple examples + case2ex_dir = root_temp_dir / "case2" / "docs" / "examples" case2a = ( - examples_dir - / "case2" - / "full_pack" - / "example1" - / "solution" - / "diffpy-cmi" - ) # full_pack, example1 + case2ex_dir / "full_pack" / "ex1" / "solution" / "diffpy-cmi" + ) # full_pack, ex1 case2a.mkdir(parents=True, exist_ok=True) (case2a / "script1.py").touch() case2b = ( - examples_dir / "case2" / "full_pack" / "example2" / "random" / "path" - ) # full_pack, example2 + case2ex_dir / "full_pack" / "ex2" / "random" / "path" + ) # full_pack, ex2 case2b.mkdir(parents=True, exist_ok=True) (case2b / "script1.py").touch() (case2b / "script2.py").touch() + case2req_dir = root_temp_dir / "case2" / "requirements" / "packs" + case2req_dir.mkdir(parents=True, exist_ok=True) - # # Case 3: multiple packs with multiple examples - case3a = examples_dir / "case3" / "packA" / "my_ex1" # packA, ex1 + # Case 3: multiple packs with multiple examples + case3ex_dir = root_temp_dir / "case3" / "docs" / "examples" + case3a = case3ex_dir / "packA" / "ex1" # packA, ex1 case3a.mkdir(parents=True, exist_ok=True) (case3a / "script1.py").touch() - case3b = ( - examples_dir / "case3" / "packA" / "my_ex2" / "solutions" - ) # packA, ex2 + case3b = case3ex_dir / "packA" / "ex2" / "solutions" # packA, ex2 case3b.mkdir(parents=True, exist_ok=True) (case3b / "script2.py").touch() case3c = ( - examples_dir / "case3" / "packB" / "ex1" / "more" / "random" / "path" - ) # packB, ex1 + case3ex_dir / "packB" / "ex3" / "more" / "random" / "path" + ) # packB, ex3 case3c.mkdir(parents=True, exist_ok=True) (case3c / "script3.py").touch() (case3c / "script4.py").touch() + case3req_dir = root_temp_dir / "case3" / "requirements" / "packs" + case3req_dir.mkdir(parents=True, exist_ok=True) - # # Case 4: no pack found (empty directory) - case4 = examples_dir / "case4" + # Case 4: no pack found (empty directory) + case4ex_dir = root_temp_dir / "case4" / "docs" / "examples" + case4 = case4ex_dir case4.mkdir(parents=True, exist_ok=True) + case4req_dir = root_temp_dir / "case4" / "requirements" / "packs" + case4req_dir.mkdir(parents=True, exist_ok=True) # Case 5: multiple packs with the same example names - case5a = examples_dir / "case5" / "packA" / "example" / "path1" + case5ex_dir = root_temp_dir / "case5" / "docs" / "examples" + case5a = case5ex_dir / "packA" / "ex1" / "path1" # packA, ex1 case5a.mkdir(parents=True, exist_ok=True) (case5a / "script1.py").touch() - case5b = examples_dir / "case5" / "packB" / "example" / "path2" + case5b = case5ex_dir / "packB" / "ex1" / "path2" # packB, ex1 case5b.mkdir(parents=True, exist_ok=True) (case5b / "script2.py").touch() + case5req_dir = root_temp_dir / "case5" / "requirements" / "packs" + case5req_dir.mkdir(parents=True, exist_ok=True) - yield examples_dir + yield root_temp_dir @pytest.fixture(scope="session") diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 335f0a5..d845ced 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -22,8 +22,8 @@ "case2", { "full_pack": [ - ("example1", "case2/full_pack/example1"), - ("example2", "case2/full_pack/example2"), + ("ex1", "case2/docs/examples/full_pack/ex1"), + ("ex2", "case2/docs/examples/full_pack/ex2"), ] }, ), @@ -32,10 +32,10 @@ "case3", { "packA": [ - ("my_ex1", "case3/packA/my_ex1"), - ("my_ex2", "case3/packA/my_ex2"), + ("ex1", "case3/docs/examples/packA/ex1"), + ("ex2", "case3/docs/examples/packA/ex2"), ], - "packB": [("ex1", "case3/packB/ex1")], + "packB": [("ex3", "case3/docs/examples/packB/ex3")], }, ), ( # case 4: no pack found. Expect {} @@ -47,43 +47,45 @@ "case5", { "packA": [ - ("example", "case5/packA/example"), + ("ex1", "case5/docs/examples/packA/ex1"), ], "packB": [ - ("example", "case5/packB/example"), + ("ex1", "case5/docs/examples/packB/ex1"), ], }, ), ] +def paths_match(expected, actual, root): + """Compare two (example_name, path) lists ignoring temp dir + differences.""" + if len(expected) != len(actual): + return False + for (exp_name, exp_path), (act_name, act_path) in zip(expected, actual): + if exp_name != act_name: + return False + actual_rel_path = str(act_path.relative_to(root)) + if actual_rel_path != exp_path: + return False + return True + + @pytest.mark.parametrize("input,expected", example_params) def test_available_examples(input, expected, example_cases): - tmp_ex_dir = example_cases / input - pkmg = PacksManager(tmp_ex_dir) - # Ensure the example directory is correctly set - assert pkmg.examples_dir == tmp_ex_dir + case_dir = example_cases / input + pkmg = PacksManager(case_dir) actual = pkmg.available_examples() - # Verify that the keys (pack names) are correct - assert set(actual.keys()) == set(expected.keys()) - # Verify that each expected example exists in actual - for expected_pack, expected_list in expected.items(): - actual_list = actual[expected_pack] - for (expected_exname, expected_path), ( - actual_exname, - actual_path, - ) in zip(expected_list, actual_list): - # Checks example name and path - assert expected_exname == actual_exname - assert expected_path == str(actual_path.relative_to(example_cases)) + assert actual.keys() == expected.keys() + for pack in expected: + assert paths_match(expected[pack], actual[pack], example_cases) @pytest.mark.parametrize("input,expected", example_params) -def test_tmp_(input, expected, example_cases): +def test_tmp_file_structure(input, expected, example_cases): example_path = example_cases / input for path in example_path.rglob("*"): if path.suffix: - # Checks temp files are files and not dirs assert path.is_file() else: assert path.is_dir() From 0d08dbecc2eca7eaae6a11bab0b559b992831718 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 17:48:43 -0400 Subject: [PATCH 29/32] change wording for comment --- tests/test_packsmanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index d845ced..4645a59 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -42,7 +42,7 @@ "case4", {}, ), - ( # case 5: multiple packs with the same example names + ( # case 5: multiple packs with duplicate example names # Expect dict with multiple pack:tuple pairs "case5", { From fcbb1a242a01839c1b518fc2be7cb52d1c825e59 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 17:55:29 -0400 Subject: [PATCH 30/32] update innit to accept root_path --- src/diffpy/cmi/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/diffpy/cmi/__init__.py b/src/diffpy/cmi/__init__.py index a92b2bb..6253d84 100644 --- a/src/diffpy/cmi/__init__.py +++ b/src/diffpy/cmi/__init__.py @@ -31,7 +31,10 @@ def get_package_dir(root_path=None): context manager A context manager that yields a pathlib.Path to the package directory. """ - resource = files(__name__) + if root_path is None: + resource = files(__name__) + else: + resource = root_path return as_file(resource) From 52aa4e7cb25623f0a3f70e6b794428f9b01cabfe Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 9 Oct 2025 18:00:11 -0400 Subject: [PATCH 31/32] better function name --- tests/test_packsmanager.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_packsmanager.py b/tests/test_packsmanager.py index 4645a59..d3af5d8 100644 --- a/tests/test_packsmanager.py +++ b/tests/test_packsmanager.py @@ -57,7 +57,7 @@ ] -def paths_match(expected, actual, root): +def paths_and_names_match(expected, actual, root): """Compare two (example_name, path) lists ignoring temp dir differences.""" if len(expected) != len(actual): @@ -78,7 +78,9 @@ def test_available_examples(input, expected, example_cases): actual = pkmg.available_examples() assert actual.keys() == expected.keys() for pack in expected: - assert paths_match(expected[pack], actual[pack], example_cases) + assert paths_and_names_match( + expected[pack], actual[pack], example_cases + ) @pytest.mark.parametrize("input,expected", example_params) From e8c8ee59f7d9a9f565821e64f7c53f93ba259e2a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 10 Oct 2025 09:37:06 -0400 Subject: [PATCH 32/32] revert some files to upstream/main, doing only dict building tests on this PR --- src/diffpy/cmi/cli.py | 39 +-------------------------------------- tests/test__init__.py | 11 ----------- 2 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 tests/test__init__.py diff --git a/src/diffpy/cmi/cli.py b/src/diffpy/cmi/cli.py index 88bf448..f25cb78 100644 --- a/src/diffpy/cmi/cli.py +++ b/src/diffpy/cmi/cli.py @@ -26,7 +26,7 @@ # Examples -def _get_examples_dir(root_path=None) -> Path: +def _get_examples_dir() -> Path: """Return the absolute path to the installed examples directory. Returns @@ -72,43 +72,6 @@ def map_pack_to_examples() -> dict[str, List[str]]: return examples_by_pack -def copy_examples( - examples: List[str], - target_dir: Optional[Path] = None, -) -> List[Path]: - """Copy one or more examples to a target directory. - - Parameters - ---------- - examples : list of str - Example name(s): ['example1'], ['pack1'] - target_dir : Path, optional - Target directory where examples should be copied. - Defaults to current working directory if not specified. - - Returns - ------- - list of Path - List of destination paths created. - - Raises - ------ - ValueError - If example name is ambiguous (exists in multiple packs). - FileNotFoundError - If example does not exist. - FileExistsError - If destination exists and overwrite=False. - """ - return - - -def print_info(pack_examples_dict): - """Pretty print available and installed packs and examples to - console.""" - return - - def copy_example(pack_example: str) -> Path: """Copy an example into the current working directory. diff --git a/tests/test__init__.py b/tests/test__init__.py deleted file mode 100644 index f75aabd..0000000 --- a/tests/test__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# from diffpy.cmi import get_package_dir -from pathlib import Path - -import pytest - - -@pytest.mark.parametrize("root_path", [None, str(Path(__file__).parent)]) -def test_get_package_dir(root_path): - """Test that get_package_dir returns a valid path context - manager.""" - assert False