diff --git a/cylindra_builtins/_pytest_fixtures.py b/cylindra_builtins/_pytest_fixtures.py index 68504399..55000300 100644 --- a/cylindra_builtins/_pytest_fixtures.py +++ b/cylindra_builtins/_pytest_fixtures.py @@ -1,3 +1,4 @@ +import sys from contextlib import suppress import pytest @@ -33,3 +34,29 @@ def ui(make_napari_viewer, request: "pytest.FixtureRequest"): sv.close() StaParameters._viewer = None viewer.close() + + +@pytest.fixture +def run_cli(make_napari_viewer, monkeypatch): + from magicclass.utils import thread_worker + from magicgui.application import use_app + + from cylindra.__main__ import main + from cylindra.cli import set_testing + from cylindra.core import ACTIVE_WIDGETS + + viewer = make_napari_viewer() + set_testing(True) + monkeypatch.setattr("builtins.input", lambda *_: "") + + def _run_cli(*args): + sys.argv = [str(a) for a in args] + main(viewer, ignore_sys_exit=True) + + with thread_worker.blocking_mode(): + yield _run_cli + + for widget in ACTIVE_WIDGETS: + widget.close() + ACTIVE_WIDGETS.clear() + use_app().process_events() diff --git a/tests/test_gui_0.py b/tests/test_gui_0.py index 717b243d..013524f9 100644 --- a/tests/test_gui_0.py +++ b/tests/test_gui_0.py @@ -18,9 +18,7 @@ from cylindra import _config, cylmeasure, view_project from cylindra._config import get_config -from cylindra.const import ( - MoleculesHeader as Mole, -) +from cylindra.const import MoleculesHeader as Mole from cylindra.const import PropertyNames as H from cylindra.widgets import CylindraMainWidget from cylindra.widgets.sta import MaskChoice, TemplateChoice @@ -1260,108 +1258,6 @@ def test_spline_fitter(ui: CylindraMainWidget): ui.macro.redo() -def test_cli(make_napari_viewer, monkeypatch): - import sys - - from cylindra.__main__ import main - from cylindra.cli import set_testing - from cylindra.core import ACTIVE_WIDGETS - - viewer: napari.Viewer = make_napari_viewer() - set_testing(True) - - def run_cli(*args): - sys.argv = [str(a) for a in args] - main(viewer, ignore_sys_exit=True) - - # test help - for cmd in [ - "average", - "config", - "find", - "new", - "open", - "plugin", - "preview", - "run", - "workflow", - ]: - run_cli("cylindra", cmd, "--help") - with thread_worker.blocking_mode(): - run_cli("cylindra") - run_cli("cylindra", "preview", PROJECT_DIR_14PF / "project.json") - run_cli("cylindra", "preview", PROJECT_DIR_14PF / "project.json", "--gui") - run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_tar.tar") - run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_zip.zip") - run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_tar.tar::project.json") - run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_tar.tar::Mole-0.csv") - - with tempfile.TemporaryDirectory() as dirpath: - run_cli( - "cylindra", "new", - Path(dirpath) / "test-project", - "--image", TEST_DIR / "14pf_MT.tif", - "--multiscales", "1", "2", - "--missing_wedge", "-60", "50", - "--molecules", PROJECT_DIR_14PF / "Mole-*", - ) # fmt: skip - run_cli("cylindra", "open", Path(dirpath) / "test-project") - run_cli("cylindra", "config", "--list") - run_cli("cylindra", "config", PROJECT_DIR_13PF) - run_cli("cylindra", "config", PROJECT_DIR_14PF / "script.py", "--remove") - run_cli("cylindra", "config", PROJECT_DIR_14PF, "--remove") - run_cli("cylindra", "workflow", "--list") - with tempfile.TemporaryDirectory() as dirpath: - dirpath = Path(dirpath) - run_cli( - "cylindra", "average", - TEST_DIR / "test_project_*", - "--molecules", "Mole-*", - "--size", "10.0", - "--output", dirpath / "test.tif", - "--filter", "col('nth') % 2 == 0", - "--split", "--seed", "123", - ) # fmt: skip - run_cli("cylindra", "run", PROJECT_DIR_14PF, "--headless") - run_cli( - "cylindra", - "run", - PROJECT_DIR_14PF, - "--headless", - "-o", - dirpath / "a.tar", - ) - - run_cli("cylindra", "find", "**/*.zip") - run_cli("cylindra", "find", "**/*.zip", "--called", "register_path") - - code = "import numpy as np\ndef main(ui):\n print(ui.default_config)\n" - - with tempfile.TemporaryDirectory() as tempdir, _config.patch_workflow_path(tempdir): - Path(tempdir).joinpath("test-cli.py").write_text(code) - run_cli("cylindra", "workflow") - run_cli("cylindra", "workflow", "test-cli.py") - - with tempfile.TemporaryDirectory() as tempdir, _config.patch_config_dir(tempdir): - from cylindra.components.spline._config import SplineConfig - - d = Path(tempdir) / "temp" - d.mkdir() - config_path = d / "temp-config.json" - SplineConfig().to_file(config_path) - run_cli("cylindra", "config", config_path, "--import") - - for widget in ACTIVE_WIDGETS: - widget.close() - ACTIVE_WIDGETS.clear() - use_app().process_events() - - run_cli("cylindra", "plugin", "list") - monkeypatch.setattr("builtins.input", lambda *_: "") - with tempfile.TemporaryDirectory() as dirpath: - run_cli("cylindra", "plugin", "new", dirpath) - - def test_function_menu(make_napari_viewer): from cylindra.widgets.subwidgets import Volume diff --git a/tests/test_gui_2_cli.py b/tests/test_gui_2_cli.py new file mode 100644 index 00000000..b387b348 --- /dev/null +++ b/tests/test_gui_2_cli.py @@ -0,0 +1,111 @@ +import tempfile +from pathlib import Path + +from cylindra import _config + +from ._const import PROJECT_DIR_13PF, PROJECT_DIR_14PF, TEST_DIR + + +def test_help(run_cli): + # test help + for cmd in [ + "average", + "config", + "find", + "new", + "open", + "plugin", + "preview", + "run", + "workflow", + ]: + run_cli("cylindra", cmd, "--help") + + +def test_start_gui(run_cli): + run_cli("cylindra") + + +def test_preview(run_cli): + run_cli("cylindra", "preview", PROJECT_DIR_14PF / "project.json") + run_cli("cylindra", "preview", PROJECT_DIR_14PF / "project.json", "--gui") + run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_tar.tar") + run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_zip.zip") + run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_tar.tar::project.json") + run_cli("cylindra", "preview", PROJECT_DIR_14PF / "test_tar.tar::Mole-0.csv") + + +def test_new_and_open(run_cli): + with tempfile.TemporaryDirectory() as dirpath: + run_cli( + "cylindra", "new", + Path(dirpath) / "test-project", + "--image", TEST_DIR / "14pf_MT.tif", + "--multiscales", "1", "2", + "--missing_wedge", "-60", "50", + "--molecules", PROJECT_DIR_14PF / "Mole-*", + ) # fmt: skip + run_cli("cylindra", "open", Path(dirpath) / "test-project") + + +def test_config(run_cli): + run_cli("cylindra", "config", "--list") + run_cli("cylindra", "config", PROJECT_DIR_13PF) + run_cli("cylindra", "config", PROJECT_DIR_14PF / "script.py", "--remove") + run_cli("cylindra", "config", PROJECT_DIR_14PF, "--remove") + + with tempfile.TemporaryDirectory() as tempdir, _config.patch_config_dir(tempdir): + from cylindra.components.spline._config import SplineConfig + + d = Path(tempdir) / "temp" + d.mkdir() + config_path = d / "temp-config.json" + SplineConfig().to_file(config_path) + run_cli("cylindra", "config", config_path, "--import") + + +def test_average(run_cli): + with tempfile.TemporaryDirectory() as dirpath: + dirpath = Path(dirpath) + run_cli( + "cylindra", "average", + TEST_DIR / "test_project_*", + "--molecules", "Mole-*", + "--size", "10.0", + "--output", dirpath / "test.tif", + "--filter", "col('nth') % 2 == 0", + "--split", "--seed", "123", + ) # fmt: skip + + +def test_run(run_cli): + run_cli("cylindra", "run", PROJECT_DIR_14PF, "--headless") + run_cli( + "cylindra", + "run", + PROJECT_DIR_14PF, + "--headless", + "-o", + Path("test.tar"), + ) + + +def test_find(run_cli): + run_cli("cylindra", "find", "**/*.zip") + run_cli("cylindra", "find", "**/*.zip", "--called", "register_path") + + +def test_workflow(run_cli): + code = "import numpy as np\ndef main(ui):\n print(ui.default_config)\n" + + with tempfile.TemporaryDirectory() as tempdir, _config.patch_workflow_path(tempdir): + Path(tempdir).joinpath("test-cli.py").write_text(code) + run_cli("cylindra", "workflow") + run_cli("cylindra", "workflow", "test-cli.py") + run_cli("cylindra", "workflow", "--list") + + +def test_plugin(run_cli): + run_cli("cylindra", "plugin", "list") + with tempfile.TemporaryDirectory() as dirpath: + run_cli("cylindra", "plugin", "new", dirpath)