Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ workflows:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
filters:
tags:
only: /.*/
Expand Down
30 changes: 28 additions & 2 deletions cubids/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,40 @@


def _path_exists(path, parser):
"""Ensure a given path exists."""
"""Ensure a given path exists.
Parameters
----------
path : str
Path to check for existence.
parser : argparse.ArgumentParser
Argument parser object.
Returns
-------
pathlib.Path
Absolute path to the given location.
"""
if path is None or not Path(path).exists():
raise parser.error(f"Path does not exist: <{path}>.")
return Path(path).absolute()


def _is_file(path, parser):
"""Ensure a given path exists and it is a file."""
"""Ensure a given path exists and it is a file.
Parameters
----------
path : str
Path to check for existence.
parser : argparse.ArgumentParser
Argument parser object.
Returns
-------
pathlib.Path
Absolute path to the given location.
"""
path = _path_exists(path, parser)
if not path.is_file():
raise parser.error(f"Path should point to a file (or symlink of file): <{path}>.")
Expand Down
161 changes: 90 additions & 71 deletions cubids/tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,83 +1,102 @@
"""
This file contains unit tests for the command-line interface (CLI) of the CuBIDS package.
"""Unit tests for the command-line interface (CLI) of the CuBIDS package.

The tests cover the following functions:
- _path_exists: Tests whether a given path exists or not.
- _is_file: Tests whether a given path is a file or a directory.
- _get_parser: Tests the creation and configuration of the argument parser.
- _main: Tests the main function of the CLI.

Each test case includes assertions to verify the expected behavior of the corresponding function.

Author: [Your Name]
Date: [Current Date]
"""

import argparse
from functools import partial

import pytest

from cubids.cli import _get_parser, _is_file, _main, _path_exists


def _test_path_exists():
"""Test whether a given path exists or not.

This function tests the `_path_exists` function by providing a path that exists
and a path that does not exist.
It asserts that the function returns the expected path when the path exists,
and raises an `argparse.ArgumentTypeError` when the path does not exist.
"""
assert _path_exists("/path/to/existing/file", None) == "/path/to/existing/file"

with pytest.raises(argparse.ArgumentTypeError):
_path_exists("/path/to/nonexistent/file", None)


def _test_is_file():
"""Test whether a given path is a file or a directory.

This function tests the `_is_file` function by providing a path that is a file
and a path that is a directory.
It asserts that the function returns the expected path when the path is a file,
and raises an `argparse.ArgumentTypeError` when the path is a directory.
"""
assert _is_file("/path/to/file.txt", None) == "/path/to/file.txt"

with pytest.raises(argparse.ArgumentTypeError):
_is_file("/path/to/directory", None)


def _test_get_parser():
"""Test the creation and configuration of the argument parser.

This function tests the `_get_parser` function by asserting that the returned object is an
instance of `argparse.ArgumentParser`, and that it has the expected `prog` and `description`
attributes.
Additional assertions can be added to test the configuration of the parser.
"""
parser = _get_parser()
assert isinstance(parser, argparse.ArgumentParser)
assert parser.prog == "cubids"
assert parser.description == "Console script for cubids"
# Add more assertions for the parser configuration


def _test_main():
"""Test the main function of the CLI.

This function tests the `_main` function by providing different sets of arguments.
It asserts that the function returns the expected exit code (0 or 1) based on the provided
arguments.
"""
# Test the main function with valid arguments
argv = ["validate", "/path/to/dataset"]
assert _main(argv) == 0

# Test the main function with invalid arguments
argv = ["invalid-command", "/path/to/dataset"]
assert _main(argv) == 1

# Test the main function with missing arguments
argv = []
assert _main(argv) == 1
from cubids.cli import _is_file, _path_exists
from cubids.tests.utils import chdir


def test_path_exists(tmp_path):
"""Test whether a given path exists or not."""
parser = argparse.ArgumentParser()

# Test with an existing path
existing_path = tmp_path / "existing_file.txt"
existing_path.touch() # Create the file
result = _path_exists(str(existing_path), parser)
assert result == existing_path.absolute()

# Test with just filename
with chdir(tmp_path):
result = _path_exists("existing_file.txt", parser)
assert result == existing_path.absolute()

# Test with a non-existing path
non_existing_path = tmp_path / "non_existing_file.txt"
with pytest.raises(SystemExit):
_path_exists(str(non_existing_path), parser)

# Test within an argument parser
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
PathExists = partial(_path_exists, parser=parser)
parser.add_argument(
"existing_folder",
type=PathExists,
action="store",
)

# Test with an existing path within an argument parser
parser.parse_args([str(existing_path)])

# Test with just filename
with chdir(tmp_path):
parser.parse_args(["existing_file.txt"])

# Test with a non-existing path within an argument parser
with pytest.raises(SystemExit):
parser.parse_args([str(non_existing_path)])


def test_is_file(tmp_path):
"""Test whether a given path exists or not."""
parser = argparse.ArgumentParser()

# Test with an existing path
existing_path = tmp_path / "existing_file.txt"
existing_path.touch() # Create the file
result = _is_file(str(existing_path), parser)
assert result == existing_path.absolute()

# Test with just filename
with chdir(tmp_path):
result = _is_file("existing_file.txt", parser)
assert result == existing_path.absolute()

# Test with a non-existing path
non_existing_path = tmp_path / "non_existing_file.txt"
with pytest.raises(SystemExit):
_is_file(str(non_existing_path), parser)

# Test within an argument parser
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
IsFile = partial(_is_file, parser=parser)
parser.add_argument(
"existing_file",
type=IsFile,
action="store",
)

# Test with an existing path within an argument parser
parser.parse_args([str(existing_path)])

# Test with just filename
with chdir(tmp_path):
parser.parse_args(["existing_file.txt"])

# Test with a non-existing path within an argument parser
with pytest.raises(SystemExit):
parser.parse_args([str(non_existing_path)])
15 changes: 15 additions & 0 deletions cubids/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json
import os
import shutil
from contextlib import contextmanager
from pathlib import Path

import nibabel as nb
Expand Down Expand Up @@ -92,3 +93,17 @@ def _edit_a_json(json_file):
metadata["THIS_IS_A_TEST"] = True
with open(json_file, "w") as metadataw:
json.dump(metadata, metadataw)


@contextmanager
def chdir(path):
"""Temporarily change directories.

Taken from https://stackoverflow.com/a/37996581/2589328.
"""
oldpwd = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(oldpwd)
Loading