# Path: paco/apply.py
# @decorate
# def apply(coro, *args, **kw):
#     """
#     Creates a continuation coroutine function with some arguments
#     already applied.
# 
#     Useful as a shorthand when combined with other control flow functions.
#     Any arguments passed to the returned function are added to the arguments
#     originally passed to apply.
# 
#     This is similar to `paco.partial()`.
# 
#     This function can be used as decorator.
# 
#     arguments:
#         coro (coroutinefunction): coroutine function to wrap.
#         *args (mixed): mixed variadic arguments for partial application.
#         *kwargs (mixed): mixed variadic keyword arguments for partial
#             application.
# 
#     Raises:
#         TypeError: if coro argument is not a coroutine function.
# 
#     Returns:
#         coroutinefunction: wrapped coroutine function.
# 
#     Usage::
# 
#         async def hello(name, mark='!'):
#             print('Hello, {name}{mark}'.format(name=name, mark=mark))
# 
#         hello_mike = paco.apply(hello, 'Mike')
#         await hello_mike()
#         # => Hello, Mike!
# 
#         hello_mike = paco.apply(hello, 'Mike', mark='?')
#         await hello_mike()
#         # => Hello, Mike?
# 
#     """
#     assert_corofunction(coro=coro)
# 
#     @asyncio.coroutine
#     def wrapper(*_args, **_kw):
#         # Explicitely ignore wrapper arguments
#         return (yield from coro(*args, **kw))
# 
#     return wrapper
# 
# Path: tests/helpers.py
# def run_in_loop(coro, *args, **kw):
#     loop = asyncio.get_event_loop()
#     if asyncio.iscoroutinefunction(coro) or isfunction(coro):
#         coro = coro(*args, **kw)
#     return loop.run_until_complete(coro)


import asyncio
from paco import apply
from .helpers import run_in_loop
# -*- coding: utf-8 -*-


@asyncio.coroutine
def coro(*args, **kw):
    return args, kw


def test_apply():
    task = apply(coro, 1, 2, foo='bar')
    args, kw = run_in_loop(task)

    assert len(args) == 2
    assert len(kw) == 1
    assert args == (1, 2)
    assert kw == {'foo': 'bar'}


def test_apply_variadic_arguments():
    task = apply(coro, *(1, 2, 3, 4))
    args, kw = run_in_loop(task)

    assert len(args) == 4
    assert len(kw) == 0
    assert args == (1, 2, 3, 4)


def test_apply_ignore_call_arguments():
    task = apply(coro, 1, 2, foo='bar')

# Path: paco/apply.py
# @decorate
# def apply(coro, *args, **kw):
#     """
#     Creates a continuation coroutine function with some arguments
#     already applied.
# 
#     Useful as a shorthand when combined with other control flow functions.
#     Any arguments passed to the returned function are added to the arguments
#     originally passed to apply.
# 
#     This is similar to `paco.partial()`.
# 
#     This function can be used as decorator.
# 
#     arguments:
#         coro (coroutinefunction): coroutine function to wrap.
#         *args (mixed): mixed variadic arguments for partial application.
#         *kwargs (mixed): mixed variadic keyword arguments for partial
#             application.
# 
#     Raises:
#         TypeError: if coro argument is not a coroutine function.
# 
#     Returns:
#         coroutinefunction: wrapped coroutine function.
# 
#     Usage::
# 
#         async def hello(name, mark='!'):
#             print('Hello, {name}{mark}'.format(name=name, mark=mark))
# 
#         hello_mike = paco.apply(hello, 'Mike')
#         await hello_mike()
#         # => Hello, Mike!
# 
#         hello_mike = paco.apply(hello, 'Mike', mark='?')
#         await hello_mike()
#         # => Hello, Mike?
# 
#     """
#     assert_corofunction(coro=coro)
# 
#     @asyncio.coroutine
#     def wrapper(*_args, **_kw):
#         # Explicitely ignore wrapper arguments
#         return (yield from coro(*args, **kw))
# 
#     return wrapper
# 
# Path: tests/helpers.py
# def run_in_loop(coro, *args, **kw):
#     loop = asyncio.get_event_loop()
#     if asyncio.iscoroutinefunction(coro) or isfunction(coro):
#         coro = coro(*args, **kw)
#     return loop.run_until_complete(coro)


# Path: tests/apply_test.py
import asyncio
from paco import apply
from .helpers import run_in_loop

# -*- coding: utf-8 -*-


@asyncio.coroutine
def coro(*args, **kw):
    return args, kw


def test_apply():
    task = apply(coro, 1, 2, foo='bar')
    args, kw = run_in_loop(task)

    assert len(args) == 2
    assert len(kw) == 1
    assert args == (1, 2)
    assert kw == {'foo': 'bar'}


def test_apply_variadic_arguments():
    task = apply(coro, *(1, 2, 3, 4))
    args, kw = run_in_loop(task)

    assert len(args) == 4
    assert len(kw) == 0
    assert args == (1, 2, 3, 4)


def test_apply_ignore_call_arguments():
    task = apply(coro, 1, 2, foo='bar')

    args, kw = run_in_loop(task, 1, 2, bar='foo')