<filename>tests/test_core.py
import unittest
from enum import Enum

from click.testing import CliRunner
from glacier.core import _get_click_command, glacier_group

from tests.utils import get_options, get_values


class Env(Enum):
    DEV = 'development'
    PROD = 'production'


def my_function_google(
    _path: str,
    name: str,
    age: int,
    is_test: bool,
    env: Env,
    verbose: bool = False,
) -> None:
    """
    This is my test function for generating CLI entrypoint.

    Args:
        _path: path input
        name: Name of the user.
        age: Age of the user.
        is_test: whether it is test or not.
        env: Environment where to run the CLI.
        verbose: If set, verbose output will be shown.
    """
    # Check if all arguments have the propery type.
    assert type(_path) == str
    assert type(name) == str
    assert type(age) == int
    assert type(is_test) == bool
    assert isinstance(env, Env)
    assert type(verbose) == bool

    # Print all values
    print(f'_path={_path}')
    print(f'name={name}')
    print(f'age={age}')
    print(f'is_test={is_test}')
    print(f'env={env}')
    print(f'verbose={verbose}')
    return


def my_function_numpy_docstring(
    _path: str,
    name: str,
    age: int,
    is_test: bool,
    env: Env,
    verbose: bool = False,
) -> None:
    """
    This is my test function for generating CLI entrypoint.

    Parameters
    ----------
    _path: str
        path input
    name: str
        Name of the user.
    age: int
        Age of the user.
    is_test: bool
        whether it is test or not.
    env: Env
        Environment where to run the CLI.
    verbose: bool
        If set, verbose output will be shown.
    """
    # Check if all arguments have the propery type.
    assert type(_path) == str
    assert type(name) == str
    assert type(age) == int
    assert type(is_test) == bool
    assert isinstance(env, Env)
    assert type(verbose) == bool

    # Print all values
    print(f'_path={_path}')
    print(f'name={name}')
    print(f'age={age}')
    print(f'is_test={is_test}')
    print(f'env={env}')
    print(f'verbose={verbose}')
    return


def my_function_restructured_text_docstring(
    _path: str,
    name: str,
    age: int,
    is_test: bool,
    env: Env,
    verbose: bool = False,
) -> None:
    """
    This is my test function for generating CLI entrypoint.

    :param _path: path input
    :param name: Name of the user.
    :param age: Age of the user.
    :param is_test: whether it is test or not.
    :param env: Environment where to run the CLI.
    :param verbose: If set, verbose output will be shown.
    """
    # Check if all arguments have the propery type.
    assert type(_path) == str
    assert type(name) == str
    assert type(age) == int
    assert type(is_test) == bool
    assert isinstance(env, Env)
    assert type(verbose) == bool

    # Print all values
    print(f'_path={_path}')
    print(f'name={name}')
    print(f'age={age}')
    print(f'is_test={is_test}')
    print(f'env={env}')
    print(f'verbose={verbose}')
    return


class TestCore(unittest.TestCase):

    def test_glacier_ok(self) -> None:
        """
        Appropriate pattern (perfectly happy path).
        """
        for function in [
            my_function_google,
            my_function_numpy_docstring,
            my_function_restructured_text_docstring,
        ]:
            f = _get_click_command(function)
            runner = CliRunner()

            # All required arguments are provided, and
            # verbose (default value is set) is omitted.
            result = runner.invoke(f, [
                'path',
                '--name=taro',
                '--age=10',
                '--is-test',
                '--env=development',
            ])
            # No excption occurs
            assert not result.exception

            # Get output
            res_d = get_values(result.output)
            assert res_d['_path'] == 'path'
            assert res_d['name'] == 'taro'
            assert res_d['age'] == '10'
            assert res_d['is_test'] == 'True'
            assert res_d['env'] == 'Env.DEV'
            assert res_d['verbose'] == 'False'
        return

    def test_glacier_help(self) -> None:
        """
        Check if help of CLI is correct.
        """
        for function in [
            my_function_google,
            my_function_numpy_docstring,
            my_function_restructured_text_docstring,
        ]:
            f = _get_click_command(function)
            runner = CliRunner()
            result = runner.invoke(f, [
                '-h',
            ])
            # No exception occurs.
            assert not result.exception
            # Assert that docstring description is contained in help.
            assert (
                'This is my test function for generating CLI entrypoint.'
                in result.output
            )

            # Assert that options are displayed in order.
            help_options = get_options(result.output)

            # Assert the name (and its order) of options
            assert help_options[0].name == 'name'
            assert help_options[1].name == 'age'
            assert help_options[2].name == 'is-test'
            assert help_options[3].name == 'env'
            assert help_options[4].name == 'verbose'

            # Assert that desired description is included in each line
            assert 'Name of the user' in help_options[0].line
            assert 'Age of the user.' in help_options[1].line
            assert 'whether it is test or not.' in help_options[2].line
            assert 'Environment where to run the CLI.' in help_options[3].line
            assert 'If set, verbose output will be shown.' in help_options[4].line
        return

    def test_glacier_nestes_groups(self) -> None:
        """
        Check if CLI with nested click.group works correctly.
        """

        def a_1() -> None:
            print('a_1')

        def a_2() -> None:
            print('a_2')

        def b() -> None:
            print('b')

        f = glacier_group({
            'a': [
                a_1,
                a_2,
            ],
            'b': b,
        })
        runner = CliRunner()
        assert runner.invoke(f, [
            'a', 'a-1',
        ]).output == 'a_1\n'
        assert runner.invoke(f, [
            'a', 'a-2',
        ]).output == 'a_2\n'
        assert runner.invoke(f, [
            'b',
        ]).output == 'b\n'
        return


async def my_async_function(_a: str, b: int) -> None:
    print('foo')


class TestCoreAsync(unittest.TestCase):

    def test_async_function(_) -> None:
        f = _get_click_command(my_async_function)
        runner = CliRunner()
        result = runner.invoke(f, [
            'a',
            '--b=10',
        ])
        assert result.stdout.strip() == 'foo'

<filename>tests/test_core.py
import unittest
from enum import Enum

from click.testing import CliRunner
from glacier.core import _get_click_command, glacier_group

from tests.utils import get_options, get_values


class Env(Enum):
    DEV = 'development'
    PROD = 'production'


def my_function_google(
    _path: str,
    name: str,
    age: int,
    is_test: bool,
    env: Env,
    verbose: bool = False,
) -> None:
    """
    This is my test function for generating CLI entrypoint.

    Args:
        _path: path input
        name: Name of the user.
        age: Age of the user.
        is_test: whether it is test or not.
        env: Environment where to run the CLI.
        verbose: If set, verbose output will be shown.
    """
    # Check if all arguments have the propery type.
    assert type(_path) == str
    assert type(name) == str
    assert type(age) == int
    assert type(is_test) == bool
    assert isinstance(env, Env)
    assert type(verbose) == bool

    # Print all values
    print(f'_path={_path}')
    print(f'name={name}')
    print(f'age={age}')
    print(f'is_test={is_test}')
    print(f'env={env}')
    print(f'verbose={verbose}')
    return


def my_function_numpy_docstring(
    _path: str,
    name: str,
    age: int,
    is_test: bool,
    env: Env,
    verbose: bool = False,
) -> None:
    """
    This is my test function for generating CLI entrypoint.

    Parameters
    ----------
    _path: str
        path input
    name: str
        Name of the user.
    age: int
        Age of the user.
    is_test: bool
        whether it is test or not.
    env: Env
        Environment where to run the CLI.
    verbose: bool
        If set, verbose output will be shown.
    """
    # Check if all arguments have the propery type.
    assert type(_path) == str
    assert type(name) == str
    assert type(age) == int
    assert type(is_test) == bool
    assert isinstance(env, Env)
    assert type(verbose) == bool

    # Print all values
    print(f'_path={_path}')
    print(f'name={name}')
    print(f'age={age}')
    print(f'is_test={is_test}')
    print(f'env={env}')
    print(f'verbose={verbose}')
    return


def my_function_restructured_text_docstring(
    _path: str,
    name: str,
    age: int,
    is_test: bool,
    env: Env,
    verbose: bool = False,
) -> None:
    """
    This is my test function for generating CLI entrypoint.

    :param _path: path input
    :param name: Name of the user.
    :param age: Age of the user.
    :param is_test: whether it is test or not.
    :param env: Environment where to run the CLI.
    :param verbose: If set, verbose output will be shown.
    """
    # Check if all arguments have the propery type.
    assert type(_path) == str
    assert type(name) == str
    assert type(age) == int
    assert type(is_test) == bool
    assert isinstance(env, Env)
    assert type(verbose) == bool

    # Print all values
    print(f'_path={_path}')
    print(f'name={name}')
    print(f'age={age}')
    print(f'is_test={is_test}')
    print(f'env={env}')
    print(f'verbose={verbose}')
    return


class TestCore(unittest.TestCase):

    def test_glacier_ok(self) -> None:
        """
        Appropriate pattern (perfectly happy path).
        """
        for function in [
            my_function_google,
            my_function_numpy_docstring,
            my_function_restructured_text_docstring,
        ]:
            f = _get_click_command(function)
            runner = CliRunner()

            # All required arguments are provided, and
            # verbose (default value is set) is omitted.
            result = runner.invoke(f, [
                'path',
                '--name=taro',
                '--age=10',
                '--is-test',
                '--env=development',
            ])
            # No excption occurs
            assert not result.exception

            # Get output
            res_d = get_values(result.output)
            assert res_d['_path'] == 'path'
            assert res_d['name'] == 'taro'
            assert res_d['age'] == '10'
            assert res_d['is_test'] == 'True'
            assert res_d['env'] == 'Env.DEV'
            assert res_d['verbose'] == 'False'
        return

    def test_glacier_help(self) -> None:
        """
        Check if help of CLI is correct.
        """
        for function in [
            my_function_google,
            my_function_numpy_docstring,
            my_function_restructured_text_docstring,
        ]:
            f = _get_click_command(function)
            runner = CliRunner()
            result = runner.invoke(f, [
                '-h',
            ])
            # No exception occurs.
            assert not result.exception
            # Assert that docstring description is contained in help.
            assert (
                'This is my test function for generating CLI entrypoint.'
                in result.output
            )

            # Assert that options are displayed in order.
            help_options = get_options(result.output)

            # Assert the name (and its order) of options
            assert help_options[0].name == 'name'
            assert help_options[1].name == 'age'
            assert help_options[2].name == 'is-test'
            assert help_options[3].name == 'env'
            assert help_options[4].name == 'verbose'

            # Assert that desired description is included in each line
            assert 'Name of the user' in help_options[0].line
            assert 'Age of the user.' in help_options[1].line
            assert 'whether it is test or not.' in help_options[2].line
            assert 'Environment where to run the CLI.' in help_options[3].line
            assert 'If set, verbose output will be shown.' in help_options[4].line
        return

    def test_glacier_nestes_groups(self) -> None:
        """
        Check if CLI with nested click.group works correctly.
        """

        def a_1() -> None:
            print('a_1')

        def a_2() -> None:
            print('a_2')

        def b() -> None:
            print('b')

        f = glacier_group({
            'a': [
                a_1,
                a_2,
            ],
            'b': b,
        })
        runner = CliRunner()
        assert runner.invoke(f, [
            'a', 'a-1',
        ]).output == 'a_1\n'
        assert runner.invoke(f, [
            'a', 'a-2',
        ]).output == 'a_2\n'
        assert runner.invoke(f, [
            'b',
        ]).output == 'b\n'
        return


async def my_async_function(_a: str, b: int) -> None:
    print('foo')


class TestCoreAsync(unittest.TestCase):

    def test_async_function(_) -> None:
        f = _get_click_command(my_async_function)
        runner = CliRunner()
        result = runner.invoke(f, [
            'a',
            '--b=10',
        ])
        assert result.stdout.strip() == 'foo'

This is my test function for generating CLI entrypoint.      Args:         _path: path input         name: Name of the user.         age: Age of the user.         is_test: whether it is test or not.         env: Environment where to run the CLI.         verbose: If set, verbose output will be shown. # Check if all arguments have the propery type. # Print all values This is my test function for generating CLI entrypoint.      Parameters     ----------     _path: str         path input     name: str         Name of the user.     age: int         Age of the user.     is_test: bool         whether it is test or not.     env: Env         Environment where to run the CLI.     verbose: bool         If set, verbose output will be shown. # Check if all arguments have the propery type. # Print all values This is my test function for generating CLI entrypoint.      :param _path: path input     :param name: Name of the user.     :param age: Age of the user.     :param is_test: whether it is test or not.     :param env: Environment where to run the CLI.     :param verbose: If set, verbose output will be shown. # Check if all arguments have the propery type. # Print all values Appropriate pattern (perfectly happy path). # All required arguments are provided, and # verbose (default value is set) is omitted. # No excption occurs # Get output Check if help of CLI is correct. # No exception occurs. # Assert that docstring description is contained in help. # Assert that options are displayed in order. # Assert the name (and its order) of options # Assert that desired description is included in each line Check if CLI with nested click.group works correctly.