import io
import unittest
from contextlib import redirect_stdout
from unittest import mock

from cpbox.tool import functocli


class TestFunc(unittest.TestCase):
    def test_default_method(self):
        class SimpleApp(functocli.BaseCliApp):
            def ping(self):
                print('pong')

        with mock.patch('sys.argv', ['prog']):
            buf = io.StringIO()
            with redirect_stdout(buf):
                functocli.run_app(SimpleApp, default_method='ping')
        self.assertIn('pong', buf.getvalue())

    def test_bool_arg_parse(self):
        class BoolApp(functocli.BaseCliApp):
            def flag(self, enabled=False):
                print('enabled=%s' % enabled)

        with mock.patch('sys.argv', ['prog', 'flag', '--enabled', 'true']):
            buf = io.StringIO()
            with redirect_stdout(buf):
                functocli.run_app(BoolApp)
        self.assertIn('enabled=True', buf.getvalue())

    def test_common_args_option(self):
        class CommonApp(functocli.BaseCliApp):
            def __init__(self, env=None):
                functocli.BaseCliApp.__init__(self)
                self.env = env

            def show(self):
                print('env=%s' % self.env)

        common_args_option = {
            'args': ['env'],
            'default_values': {'env': 'dev'}
        }

        with mock.patch('sys.argv', ['prog', 'show', '--env', 'prod']):
            buf = io.StringIO()
            with redirect_stdout(buf):
                functocli.run_app(CommonApp, common_args_option=common_args_option)
        self.assertIn('env=prod', buf.getvalue())

    def test_common_args_auto_from_init(self):
        class AutoApp(functocli.BaseCliApp):
            def __init__(self, app_name, verbose=False):
                functocli.BaseCliApp.__init__(self)
                self.app_name = app_name
                self.verbose = verbose

            def show(self):
                print('app_name=%s verbose=%s' % (self.app_name, self.verbose))

        with mock.patch('sys.argv', ['prog', 'show', '--app_name', 'demo', '--verbose', 'true']):
            buf = io.StringIO()
            with redirect_stdout(buf):
                functocli.run_app(AutoApp, common_args_option='auto')
        self.assertIn('app_name=demo verbose=True', buf.getvalue())



if __name__ == '__main__':
    unittest.main()
