|
14 | 14 | import importlib.util |
15 | 15 | import os |
16 | 16 | import os.path as osp |
| 17 | +import shutil |
17 | 18 | from contextlib import contextmanager |
18 | 19 | from pathlib import Path |
19 | 20 | from unittest.mock import patch |
20 | 21 |
|
| 22 | +import numpy as np |
21 | 23 | import pytest |
22 | 24 | from qtpy import QtWidgets as QW |
| 25 | +from sigima.objects import create_image |
23 | 26 | from sigima.tests.data import create_paracetamol_signal |
24 | 27 |
|
25 | 28 | from datalab.config import Conf |
@@ -814,6 +817,77 @@ def test_plugin_examples_import() -> None: |
814 | 817 | spec.loader.exec_module(module) |
815 | 818 |
|
816 | 819 |
|
| 820 | +#: Shipped example plugins, by module, with the stable ID of their plugin class |
| 821 | +#: (the image format example only declares a file format) |
| 822 | +SHIPPED_EXAMPLES = { |
| 823 | + "datalab_custom_func": "org.datalab.examples.custom-filters", |
| 824 | + "datalab_example_dialogs": "org.datalab.examples.dialog-methods", |
| 825 | + "datalab_example_empty": "org.datalab.examples.empty", |
| 826 | + "datalab_example_imageformat": None, |
| 827 | + "datalab_example_imageproc": "org.datalab.examples.extract-blobs", |
| 828 | + "datalab_example_nested_menus": "org.datalab.examples.nested-menus", |
| 829 | + "datalab_exemple_contour_plot": "org.datalab.examples.contour-plot", |
| 830 | +} |
| 831 | + |
| 832 | + |
| 833 | +def _run_custom_filter(win: DLMainWindow) -> np.ndarray: |
| 834 | + """Run the processing of the custom function example on a new image. |
| 835 | +
|
| 836 | + Returns: |
| 837 | + Data of the processed image |
| 838 | + """ |
| 839 | + menus = [ |
| 840 | + item |
| 841 | + for item in win.imagepanel.get_category_actions(ActionCategory.PLUGINS) |
| 842 | + if isinstance(item, QW.QMenu) and item.title() == "My custom filters" |
| 843 | + ] |
| 844 | + assert len(menus) == 1, "'My custom filters' menu not found" |
| 845 | + menus[0].aboutToShow.emit() |
| 846 | + assert [action.text() for action in menus[0].actions()] == [ |
| 847 | + "Weighted average denoise" |
| 848 | + ] |
| 849 | + data = np.arange(64, dtype=float).reshape(8, 8) |
| 850 | + win.imagepanel.add_object(create_image("Ramp", data)) |
| 851 | + count = len(win.imagepanel) |
| 852 | + win.imagepanel.processor.run_feature( |
| 853 | + "org.datalab.examples.custom-filters:weighted-average-denoise" |
| 854 | + ) |
| 855 | + assert len(win.imagepanel) == count + 1 |
| 856 | + return win.imagepanel[len(win.imagepanel)].data |
| 857 | + |
| 858 | + |
| 859 | +@enabled_plugins_context() |
| 860 | +def test_shipped_plugin_examples_load_in_datalab() -> None: |
| 861 | + """All shipped examples load in DataLab, and their processing runs.""" |
| 862 | + examples_dir = Path(__file__).parents[4] / "plugins" / "examples" |
| 863 | + assert {path.stem for path in examples_dir.glob("*.py")} == set(SHIPPED_EXAMPLES) |
| 864 | + with temporary_plugin_dir(module_prefixes=tuple(SHIPPED_EXAMPLES)) as plugin_dir: |
| 865 | + for module_name in SHIPPED_EXAMPLES: |
| 866 | + shutil.copy(examples_dir / f"{module_name}.py", plugin_dir) |
| 867 | + spec = importlib.util.spec_from_file_location( |
| 868 | + "custom_func_reference", examples_dir / "datalab_custom_func.py" |
| 869 | + ) |
| 870 | + reference = importlib.util.module_from_spec(spec) |
| 871 | + spec.loader.exec_module(reference) |
| 872 | + expected = reference.weighted_average_denoise( |
| 873 | + np.arange(64, dtype=float).reshape(8, 8) |
| 874 | + ) |
| 875 | + |
| 876 | + with datalab_test_app_context(console=False) as win: |
| 877 | + for _reload in range(2): |
| 878 | + failed = [ |
| 879 | + failed.name |
| 880 | + for failed in PluginRegistry.get_failed_plugins() |
| 881 | + if failed.name.split(".")[0] in SHIPPED_EXAMPLES |
| 882 | + ] |
| 883 | + assert not failed, f"Example plugins failed to load: {failed}" |
| 884 | + for plugin_id in filter(None, SHIPPED_EXAMPLES.values()): |
| 885 | + assert PluginRegistry.get_plugin(plugin_id) is not None, plugin_id |
| 886 | + assert np.allclose(_run_custom_filter(win), expected) |
| 887 | + win.reload_plugins() |
| 888 | + QW.QApplication.processEvents() |
| 889 | + |
| 890 | + |
817 | 891 | if __name__ == "__main__": |
818 | 892 | _launch_path = osp.join(osp.dirname(__file__), "launch_with_test_plugins.py") |
819 | 893 | _spec = importlib.util.spec_from_file_location( |
|
0 commit comments