Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
54974ba
initial listing functions for cli
cadenmyers13 Oct 6, 2025
c9cf238
initial tests
cadenmyers13 Oct 6, 2025
f9a14c3
test for listing available examples
cadenmyers13 Oct 6, 2025
71423d5
test pretty print
cadenmyers13 Oct 6, 2025
a1ee907
api for copying packs and examples
cadenmyers13 Oct 6, 2025
b16c90b
have one function for copying examples
cadenmyers13 Oct 7, 2025
15c8111
move print_info to cli, add params to docstring in available_examples
cadenmyers13 Oct 7, 2025
db2ac9a
add fnferror to api
cadenmyers13 Oct 7, 2025
9fcef71
update available_examples test
cadenmyers13 Oct 7, 2025
c70ca27
have pkmg methods take temp_path instead of pkmg
cadenmyers13 Oct 7, 2025
d32201a
test print info and test copy examples
cadenmyers13 Oct 7, 2025
fbbf88c
checkpoint1 commit of working available examples tests
cadenmyers13 Oct 7, 2025
a458c5e
checkpoint conftest, build example_cases fixture
cadenmyers13 Oct 7, 2025
736b519
checkpoint packsmanager.py file
cadenmyers13 Oct 8, 2025
0bd26fc
checkpoint: conftest is building correctly
cadenmyers13 Oct 8, 2025
4be38f6
checkpoint, working version that gets examples dir outside of PacksMa…
cadenmyers13 Oct 8, 2025
280390c
checkpoint: _get_examples_dir moved back in PacksManager and paths ar…
cadenmyers13 Oct 8, 2025
99c4951
forgot to add conftest to previous checkpoint commit, so its added in…
cadenmyers13 Oct 8, 2025
aa65d02
checkpoint: test that the path and examples match
cadenmyers13 Oct 8, 2025
4aa15b0
checkpoint: add all 4 cases to test_packsmanager
cadenmyers13 Oct 8, 2025
cfb2273
Add case 5, split into separate tests, and refactor code for style/re…
cadenmyers13 Oct 9, 2025
fdf09b2
sort packs and examples when building dict with available_examples()
cadenmyers13 Oct 9, 2025
53ac9a2
add case 5 to conftest
cadenmyers13 Oct 9, 2025
ce1efa7
remove printed fail statement
cadenmyers13 Oct 9, 2025
c39dfae
rm unused helper function I made in conftest
cadenmyers13 Oct 9, 2025
c2e8076
add comment for case5 ex
cadenmyers13 Oct 9, 2025
d1038b7
UCs for copy_examples tests
cadenmyers13 Oct 9, 2025
85bb747
treat each 'caseX' as the root dir, build out from there
cadenmyers13 Oct 9, 2025
0d08dbe
change wording for comment
cadenmyers13 Oct 9, 2025
fcbb1a2
update innit to accept root_path
cadenmyers13 Oct 9, 2025
52aa4e7
better function name
cadenmyers13 Oct 9, 2025
e8c8ee5
revert some files to upstream/main, doing only dict building tests on…
cadenmyers13 Oct 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/diffpy/cmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
39 changes: 38 additions & 1 deletion src/diffpy/cmi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -72,6 +72,43 @@ 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about:
"""Copy one or more examples from the installed package 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure we need to return this. How will it be used?

List of destination paths created.

Raises
------
ValueError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to raise this. We just copy all versions that we find. This will be a case we test.

We often don't do this Raises section, the interesting raises are caught in the tests. Maybe we should but our current style is not to. It can be tmi

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I'll leave it empty for now

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.

Expand Down
19 changes: 19 additions & 0 deletions src/diffpy/cmi/packsmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ 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):
"""Finds all examples for each pack and builds a dict.

Parameters
----------
root_path : Path
Root path to the examples directory.
Returns
-------
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

def _resolve_pack_file(self, identifier: Union[str, Path]) -> Path:
"""Resolve a pack identifier to an absolute .txt path.

Expand Down
11 changes: 11 additions & 0 deletions tests/test__init__.py
Original file line number Diff line number Diff line change
@@ -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
47 changes: 47 additions & 0 deletions tests/test_packsmanager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pytest

from diffpy.cmi.packsmanager import PacksManager


@pytest.mark.parametrize(
"expected",
[
{
# test with pack that has examples
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this?

# pack with no examples.  Expect {'empty_pack': []}
# pack with multiple examples.  Expect {'full_pack': [('example1`, path_to_1'), 'example2', path_to_2)]
# multiple packs.  Expect dict with multiple pack:tuple pairs
# no pack found. Expect {}

"pack1": [
"ex1",
"ex2",
"ex3",
]
},
{
# test pack with no examples
"no_examples": []
},
],
)
def test_available_examples(temp_path, expected):
for pack, examples in expected.items():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all wrong, but we can revisit this when we have the cases sorted out. Basically, we will need to build a different set of folders for each case and the paramertrize will have to hand the path to each case as an input. Paramatrize usually has a kind of [('input','expected')] feel to it which it doesn't atm here.

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you seem to be handing temp_path to this twice. Think about how you want it to work (the behavior you want) and then do it that way.

Copy link
Contributor Author

@cadenmyers13 cadenmyers13 Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made the change. the methods are taking temp_path as input

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(temp_path, capsys):
pkmg = PacksManager(temp_path)
pkmg.print_info()
captured = capsys.readouterr()
output = captured.out.strip()
assert "Available packs" in output or "Installed packs" in output
Loading