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

#    Copyright 2021 Fabien Bourgeois <fabien@yaltik.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

""" SHELL helpers """

from imp import reload
import unittest

def run_test(module, test_names=False, test_class_name=''):
    """ Helper to allow testing of single method or all from TestCase
    Takes module as python module, and names as strings
    module is automatically reloaded for recent updates in shell
    test_names can be only one string or an array of strings
    test_class_name can be automatically found from module name.

    For example, from Odoo SHELL, first, import the modules :

    >>> from shell_helpers import run_test
    >>> from odoo.addons.addon.tests import test_file

    Then, launch all tests from the module, and guessed className (here TestFile) :

    >>> run_test(test_file)

    Or launch only some tests :

    >>> run_test(test_file, ['test_one', 'test_two'])

    Or launch all tests from specific className :

    >>> run_test(test_file, test_class_name='TestModelOne')
    """
    module = reload(module)
    suite = unittest.TestSuite()
    if not test_class_name:
        module_name = module.__name__.split('.')[-1]
        test_class_name = ''.join(map(str.capitalize, module_name.split('_')))
    if test_class_name not in dir(module):
        raise Exception('Generated class name (%s) not found in module, please '
                        'specify' % test_class_name)
    if not test_names:
        testCase = getattr(module, test_class_name)
        tests = unittest.TestLoader().loadTestsFromTestCase(testCase)
        suite.addTests(tests)
    else:
        if isinstance(test_names, str):
            test_names = [test_names]
        add = lambda test_name: suite.addTest(getattr(module, test_class_name)(test_name))
        map(add, test_names)
    unittest.TextTestRunner().run(suite)
