# Path: gears/asset_handler.py
# class AssetHandlerError(Exception):
#     pass
# 
# class ExecMixin(object):
#     """Provides the ability to process asset through external command."""
# 
#     #: The name of the executable to run. It must be a command name, if it is
#     #: available in the PATH environment variable, or a path to the executable.
#     executable = None
# 
#     #: The list of executable parameters.
#     params = []
# 
#     def run(self, input):
#         """Runs :attr:`executable` with ``input`` as stdin.
#         :class:`AssetHandlerError` exception is raised, if execution is failed,
#         otherwise stdout is returned.
#         """
#         p = self.get_process()
#         output, errors = p.communicate(input=input.encode('utf-8'))
#         if p.returncode != 0:
#             raise AssetHandlerError(errors)
#         return output.decode('utf-8')
# 
#     def get_process(self):
#         """Returns :class:`subprocess.Popen` instance with args from
#         :meth:`get_args` result and piped stdin, stdout and stderr.
#         """
#         return Popen(self.get_args(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
# 
#     def get_args(self):
#         """Returns the list of :class:`subprocess.Popen` arguments."""
#         return [self.executable] + self.params


from gears.asset_handler import AssetHandlerError, ExecMixin
from mock import patch, Mock
from unittest2 import TestCase


class Exec(ExecMixin):
    executable = 'program'


class ExecMixinTests(TestCase):

    @patch('gears.asset_handler.Popen')
    def test_returns_stdout_on_success(self, Popen):
        result = Mock()
        result.returncode = 0
        result.communicate.return_value = (b'output', b'')
        Popen.return_value = result
        self.assertEqual(Exec().run('input'), 'output')

    @patch('gears.asset_handler.Popen')
    def test_raises_stderr_on_failure(self, Popen):

# Path: gears/asset_handler.py
# class AssetHandlerError(Exception):
#     pass
# 
# class ExecMixin(object):
#     """Provides the ability to process asset through external command."""
# 
#     #: The name of the executable to run. It must be a command name, if it is
#     #: available in the PATH environment variable, or a path to the executable.
#     executable = None
# 
#     #: The list of executable parameters.
#     params = []
# 
#     def run(self, input):
#         """Runs :attr:`executable` with ``input`` as stdin.
#         :class:`AssetHandlerError` exception is raised, if execution is failed,
#         otherwise stdout is returned.
#         """
#         p = self.get_process()
#         output, errors = p.communicate(input=input.encode('utf-8'))
#         if p.returncode != 0:
#             raise AssetHandlerError(errors)
#         return output.decode('utf-8')
# 
#     def get_process(self):
#         """Returns :class:`subprocess.Popen` instance with args from
#         :meth:`get_args` result and piped stdin, stdout and stderr.
#         """
#         return Popen(self.get_args(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
# 
#     def get_args(self):
#         """Returns the list of :class:`subprocess.Popen` arguments."""
#         return [self.executable] + self.params


# Path: tests/test_exec_mixin.py
from gears.asset_handler import AssetHandlerError, ExecMixin
from mock import patch, Mock
from unittest2 import TestCase



class Exec(ExecMixin):
    executable = 'program'


class ExecMixinTests(TestCase):

    @patch('gears.asset_handler.Popen')
    def test_returns_stdout_on_success(self, Popen):
        result = Mock()
        result.returncode = 0
        result.communicate.return_value = (b'output', b'')
        Popen.return_value = result
        self.assertEqual(Exec().run('input'), 'output')

    @patch('gears.asset_handler.Popen')
    def test_raises_stderr_on_failure(self, Popen):

        result = Mock()