From 767dfd1cd34b4310f77f767c963b23a74b56444c Mon Sep 17 00:00:00 2001 From: Michael Boniface <m.j.boniface@soton.ac.uk> Date: Tue, 18 Feb 2025 17:49:41 +0000 Subject: [PATCH] added initial pytests for basic workflow --- phen.py | 10 ++++- tests/test_acmc.py | 92 ++++++++++++++++++++++++++++++++++++++++++ tests/test_commands.py | 75 ---------------------------------- 3 files changed, 100 insertions(+), 77 deletions(-) create mode 100644 tests/test_acmc.py delete mode 100644 tests/test_commands.py diff --git a/phen.py b/phen.py index ddbd0bb..03dd22e 100644 --- a/phen.py +++ b/phen.py @@ -182,7 +182,7 @@ def init(phen_dir, remote_url): repo.git.add(all=True) repo.index.commit("initialised the phen git repo.") - print(f"Phenotype initialised") + print(f"Phenotype initialised successfully") def validate(phen_dir): """Validates the phenotype directory is a git repo with standard structure""" @@ -566,7 +566,7 @@ def map(phen_dir, target_code_type, translate=True, verify=True): print(f"Saved concept_sets to {str(concept_set_path.resolve())}") - print(f"Phenotype processing completed") + print(f"Phenotype processed successfully") def publish(phen_dir): """Publishes updates to the phenotype by commiting all changes to the repo directory""" @@ -626,6 +626,8 @@ def publish(phen_dir): except AttributeError: print("No remote named 'origin' found, local repo.") + print(f"Phenotype published successfully") + def copy(phen_dir, target_dir, version=None): """Copys a phen repo at a specific tagged version into a target directory""" @@ -666,6 +668,8 @@ def copy(phen_dir, target_dir, version=None): print(f"Copied {phen_path} {repo.head.commit.hexsha[:7]} in {copy_path}") + print(f"Phenotype copied successfully") + def diff(phen_dir, phen_old_dir): """Compare the differences between two versions of a phenotype""" @@ -738,6 +742,8 @@ def diff(phen_dir, phen_old_dir): report.write(f"- Changed concepts []\n\n") + print(f"Phenotypes diff'd successfully") + # Here's the atlas code that needs to go into anotehr function # if output_path == "atlas": # vocab_id = summary_config["omop"]["vocabulary_id"] diff --git a/tests/test_acmc.py b/tests/test_acmc.py new file mode 100644 index 0000000..4dbcf9e --- /dev/null +++ b/tests/test_acmc.py @@ -0,0 +1,92 @@ +import pytest +import argparse +import sys +import shutil + +import trud +import omop +import phen +import acmc +from pathlib import Path + +@pytest.fixture +def tmp_dir(): + # Setup tmp directory + temp_dir = Path("./tests/tmp") + temp_dir.mkdir(parents=True, exist_ok=True) + + # Yield the directory path to the test function + yield temp_dir + + # Remove the directory after the test finishes + shutil.rmtree(temp_dir) + +def test_phen_init_local_default(tmp_dir, monkeypatch, capsys): + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "init"]) + # Mock input() to return "yes" to the question about reinitialising the directory + monkeypatch.setattr("builtins.input", lambda _: "y") + acmc.main() + captured = capsys.readouterr() + assert "Phenotype initialised successfully" in captured.out + +def test_phen_init_local_specified(tmp_dir, monkeypatch, capsys): + phen_path = tmp_dir / "phen" + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "init", "-d", str(phen_path.resolve())]) + # Mock input() to return "yes" to the question about reinitialising the directory + monkeypatch.setattr("builtins.input", lambda _: "y") + acmc.main() + captured = capsys.readouterr() + assert "Phenotype initialised successfully" in captured.out + +def test_phen_workflow(tmp_dir, monkeypatch, capsys): + phen_path = tmp_dir / "phen" + phen_path = phen_path.resolve() + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "init", "-d", str(phen_path.resolve())]) + # Mock input() to return "yes" to the question about reinitialising the directory + monkeypatch.setattr("builtins.input", lambda _: "y") + acmc.main() + captured = capsys.readouterr() + assert "Phenotype initialised successfully" in captured.out + + # copy examples across + shutil.rmtree(phen_path / 'codes') + ex_path = Path('./examples').resolve() + for item in ex_path.iterdir(): + source = ex_path / item.name + destination = phen_path / item.name + if source.is_dir(): + shutil.copytree(source, destination) + else: + shutil.copy2(source, destination) + shutil.copy( phen_path / 'config1.json', phen_path / 'config.json') + + # validate phenotype + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "validate", "-d", str(phen_path.resolve())]) + acmc.main() + captured = capsys.readouterr() + assert "Phenotype validated successfully" in captured.out + + # map phenotype + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "map", "-d", str(phen_path.resolve()), "-t", "read2", "-tr", "-ve"]) + acmc.main() + captured = capsys.readouterr() + assert "Phenotype processed successfully" in captured.out + + # publish phenotype + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "publish", "-d", str(phen_path.resolve())]) + acmc.main() + captured = capsys.readouterr() + assert "Phenotype published successfully" in captured.out + + # copy phenotype' + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "copy", "-d", str(phen_path.resolve()), "-td", str(tmp_dir.resolve()), "-v", "v1.0.3"]) + acmc.main() + captured = capsys.readouterr() + assert "Phenotype copied successfully" in captured.out + + # diff phenotype + old_path = tmp_dir / "v1.0.3" + monkeypatch.setattr(sys, "argv", ["acmc.py", "phen", "diff", "-d", str(phen_path.resolve()), "-old", str(old_path.resolve())]) + acmc.main() + captured = capsys.readouterr() + assert "Phenotypes diff'd successfully" in captured.out diff --git a/tests/test_commands.py b/tests/test_commands.py deleted file mode 100644 index 375241f..0000000 --- a/tests/test_commands.py +++ /dev/null @@ -1,75 +0,0 @@ -import pytest -import argparse -from unittest.mock import patch, MagicMock - -import trud -import omop -import phen -from pathlib import Path -from acmc import trud_install, omop_install, omop_clear, omop_delete, phen_init, phen_validate, phen_map, phen_publish, phen_copy, phen_diff - -def test_trud_install(): - with patch("trud.install") as mock_install: - args = argparse.Namespace(api_key="test_key") - trud_install(args) - mock_install.assert_called_once_with("test_key") - -def test_omop_install(): - with patch("omop.install") as mock_install: - args = argparse.Namespace(omop_folder="/path/to/omop") - omop_install(args) - mock_install.assert_called_once_with(omop.OMOP_DB_PATH, "/path/to/omop") - -def test_omop_clear(): - with patch("omop.clear") as mock_clear: - args = argparse.Namespace() - omop_clear(args) - mock_clear.assert_called_once_with(omop.OMOP_DB_PATH) - -def test_omop_delete(): - with patch("omop.delete") as mock_delete: - args = argparse.Namespace() - omop_delete(args) - mock_delete.assert_called_once_with(omop.OMOP_DB_PATH) - -def test_phen_init(): - with patch("phen.init") as mock_init: - args = argparse.Namespace(phen_dir="/path/to/phen") - phen_init(args) - mock_init.assert_called_once_with("/path/to/phen") - -def test_phen_validate(): - with patch("phen.validate") as mock_validate: - args = argparse.Namespace(phen_dir="/path/to/phen") - phen_validate(args) - mock_validate.assert_called_once_with("/path/to/phen") - -def test_phen_map(): - with patch("phen.map") as mock_map: - args = argparse.Namespace(phen_dir="/path/to/phen", target_coding="icd10_code", translate=True, verify=True) - phen_map(args) - mock_map.assert_called_once_with("/path/to/phen", "icd10_code", True, True) - -def test_phen_publish(): - with patch("phen.publish") as mock_publish: - args = argparse.Namespace(phen_dir="/path/to/phen") - phen_publish(args) - mock_publish.assert_called_once_with("/path/to/phen") - -def test_phen_copy(): - with patch("phen.copy") as mock_copy: - args = argparse.Namespace(phen_dir="/path/to/phen", target_dir="/path/to/target", version="1.0") - phen_copy(args) - mock_copy.assert_called_once_with("/path/to/phen", "/path/to/target", "1.0") - -def test_phen_diff(): - with patch("phen.diff") as mock_diff: - args = argparse.Namespace(phen_dir="/path/to/phen", phen_dir_old="/path/to/old_phen") - phen_diff(args) - mock_diff.assert_called_once_with("/path/to/phen", "/path/to/old_phen") - -def test_phen_local(): - with patch("phen.diff") as mock_diff: - args = argparse.Namespace(phen_dir="/path/to/phen", phen_dir_old="/path/to/old_phen") - phen_diff(args) - mock_diff.assert_called_once_with("/path/to/phen", "/path/to/old_phen") -- GitLab