Skip to content

Commit e354cda

Browse files
committed
debugged running of generated of unittests in nipype2pydra unittests
1 parent e0b0170 commit e354cda

File tree

4 files changed

+76
-20
lines changed

4 files changed

+76
-20
lines changed

nipype2pydra/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def cli():
3434
help="a Python file containing callable functions required in the command interface",
3535
)
3636
@click.option(
37-
"--output-module" "-m",
37+
"--output-module",
38+
"-m",
3839
type=str,
3940
default=None,
4041
help=(

nipype2pydra/task.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ def output_callables_validator(self, _, output_callables: dict):
3939
def __attrs_post_init__(self):
4040
if self.output_module is None:
4141
if self.nipype_module.__name__.startswith("nipype.interfaces."):
42-
self.output_module = self.nipype_module.__name__[len("nipype.interfaces."):]
42+
self.output_module = (
43+
"pydra.tasks."
44+
+ self.nipype_module.__name__[len("nipype.interfaces.") :]
45+
+ "." + self.task_name.lower()
46+
)
4347
else:
4448
raise RuntimeError(
4549
"Output-module needs to be explicitly provided to task converter "
@@ -67,14 +71,14 @@ def generate(self, package_root: Path):
6771
input_fields, inp_templates = self.convert_input_fields()
6872
output_fields = self.convert_output_spec(fields_from_template=inp_templates)
6973

70-
module_path = (Path(package_root) / "pydra" / "tasks").joinpath(self.output_module.split("."))
71-
output_file = (module_path / self.task_name.lower()).with_suffix(".py")
74+
output_file = Path(package_root).joinpath(*self.output_module.split(".")).with_suffix(".py")
75+
testdir = output_file.parent / "tests"
76+
testdir.mkdir(parents=True)
77+
7278
self.write_task(output_file, input_fields, output_fields)
7379

74-
testdir = module_path / "tests"
75-
testdir.mkdir()
76-
filename_test = testdir / f"test_spec_{self.task_name.lower()}"
77-
filename_test_run = testdir / f"test_run_{self.task_name.lower()}"
80+
filename_test = testdir / f"test_spec_{self.task_name.lower()}.py"
81+
filename_test_run = testdir / f"test_run_{self.task_name.lower()}.py"
7882
self.write_test(filename_test=filename_test)
7983
self.write_test(filename_test=filename_test_run, run=True)
8084

@@ -359,9 +363,7 @@ def write_test(self, filename_test, run=False):
359363
tests_inp_error.append((tests_inputs[i], out))
360364

361365
spec_str = "import os, pytest \nfrom pathlib import Path\n"
362-
spec_str += (
363-
f"from pydra.tasks.{self.output_module}.{self.task_name.lower()} import {self.task_name} \n\n"
364-
)
366+
spec_str += f"from {self.output_module} import {self.task_name} \n\n"
365367
if run:
366368
pass
367369
spec_str += f"@pytest.mark.parametrize('inputs, outputs', {tests_inp_outp})\n"
@@ -399,9 +401,7 @@ def write_test_error(self, input_error):
399401
"""
400402
spec_str = "\n\n"
401403
spec_str += f"@pytest.mark.parametrize('inputs, error', {input_error})\n"
402-
spec_str += (
403-
f"def test_{self.task_name}_exception(test_data, inputs, error):\n"
404-
)
404+
spec_str += f"def test_{self.task_name}_exception(test_data, inputs, error):\n"
405405
spec_str += " in_file = Path(test_data) / 'test.nii.gz'\n"
406406
spec_str += " if inputs is None: inputs = {{}}\n"
407407
spec_str += " for key, val in inputs.items():\n"

nipype2pydra/utils.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import traceback
22
from types import ModuleType
33
import sys
4+
import os
5+
from contextlib import contextmanager
46
from pathlib import Path
7+
58
from importlib import import_module
69

710

@@ -24,3 +27,38 @@ def import_module_from_path(module_path: Path) -> ModuleType:
2427
return import_module(module_path.stem)
2528
finally:
2629
sys.path.pop(0)
30+
31+
32+
@contextmanager
33+
def set_cwd(path):
34+
"""Sets the current working directory to `path` and back to original
35+
working directory on exit
36+
37+
Parameters
38+
----------
39+
path : str
40+
The file system path to set as the current working directory
41+
"""
42+
pwd = os.getcwd()
43+
os.chdir(path)
44+
try:
45+
yield path
46+
finally:
47+
os.chdir(pwd)
48+
49+
50+
@contextmanager
51+
def add_to_sys_path(path: Path):
52+
"""Adds the given `path` to the Python system path and then reverts it back to the
53+
original value on exit
54+
55+
Parameters
56+
----------
57+
path : str
58+
The file system path to add to the system path
59+
"""
60+
sys.path.insert(0, str(path))
61+
try:
62+
yield sys.path
63+
finally:
64+
sys.path.pop(0)

tests/test_task.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
from importlib import import_module
22
import yaml
33
from conftest import show_cli_trace
4+
import pytest
5+
import logging
46
from nipype2pydra.cli import task as task_cli
5-
from nipype2pydra.utils import import_module_from_path
7+
from nipype2pydra.utils import add_to_sys_path
8+
9+
10+
logging.basicConfig(level=logging.INFO)
611

712

813
INBUILT_NIPYPE_TRAIT_NAMES = [
@@ -18,19 +23,24 @@ def test_task_conversion(task_spec_file, cli_runner, work_dir):
1823

1924
with open(task_spec_file) as f:
2025
task_spec = yaml.safe_load(f)
21-
output_file = (work_dir / task_spec_file.stem).with_suffix(".py")
26+
pkg_root = work_dir / "src"
27+
28+
output_module_path = f"nipype2pydratest.{task_spec_file.stem.lower()}"
2229

2330
result = cli_runner(
2431
task_cli,
2532
args=[
2633
str(task_spec_file),
27-
str(output_file),
34+
str(pkg_root),
35+
"--output-module",
36+
output_module_path,
2837
],
2938
)
3039

3140
assert result.exit_code == 0, show_cli_trace(result)
3241

33-
pydra_module = import_module_from_path(output_file)
42+
with add_to_sys_path(pkg_root):
43+
pydra_module = import_module(output_module_path)
3444
pydra_task = getattr(pydra_module, task_spec["task_name"])
3545
nipype_interface = getattr(
3646
import_module(task_spec["nipype_module"]), task_spec["task_name"]
@@ -43,8 +53,15 @@ def test_task_conversion(task_spec_file, cli_runner, work_dir):
4353
for n in nipype_trait_names
4454
if not (
4555
n in INBUILT_NIPYPE_TRAIT_NAMES
46-
or (n.endswith("_items") and n[:-len("_items")] in nipype_trait_names)
56+
or (n.endswith("_items") and n[: -len("_items")] in nipype_trait_names)
4757
)
4858
)
4959

50-
# TODO: More detailed tests needed here
60+
tests_fspath = pkg_root.joinpath(*output_module_path.split(".")).parent / "tests"
61+
62+
logging.info("Running generated tests for %s", output_module_path)
63+
# Run generated pytests
64+
with add_to_sys_path(pkg_root):
65+
result = pytest.main([str(tests_fspath)])
66+
67+
assert result.value == 0

0 commit comments

Comments
 (0)