# Copyright (C) 2010, 2016 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA


"""Tests for generating multiple tests for scenarios."""

from breezy.tests import TestCase, TestLoader, iter_suite_tests, multiply_tests
from breezy.tests.scenarios import (load_tests_apply_scenarios,
                                    multiply_scenarios,
                                    multiply_tests_by_their_scenarios)

# There aren't any actually parameterized tests here, but this exists as a
# demonstration; so that you can interactively observe them being multiplied;
# and so that we check everything hooks up properly.
load_tests = load_tests_apply_scenarios


def vary_by_color():
    """Very simple static variation example"""
    for color in ['red', 'green', 'blue']:
        yield (color, {'color': color})


def vary_named_attribute(attr_name):
    """More sophisticated: vary a named parameter"""
    yield ('a', {attr_name: 'a'})
    yield ('b', {attr_name: 'b'})


def get_generated_test_attributes(suite, attr_name):
    """Return the `attr_name` attribute from all tests in the suite"""
    return sorted([
        getattr(t, attr_name) for t in iter_suite_tests(suite)])


class TestTestScenarios(TestCase):

    def test_multiply_tests(self):
        loader = TestLoader()
        suite = loader.suiteClass()
        multiply_tests(
            self,
            vary_by_color(),
            suite)
        self.assertEqual(
            ['blue', 'green', 'red'],
            get_generated_test_attributes(suite, 'color'))

    def test_multiply_scenarios_from_generators(self):
        """It's safe to multiply scenarios that come from generators"""
        s = multiply_scenarios(
            vary_named_attribute('one'),
            vary_named_attribute('two'),
            )
        self.assertEqual(
            2 * 2,
            len(s),
            s)

    def test_multiply_tests_by_their_scenarios(self):
        loader = TestLoader()
        suite = loader.suiteClass()
        test_instance = PretendVaryingTest('test_nothing')
        multiply_tests_by_their_scenarios(
            test_instance,
            suite)
        self.assertEqual(
            ['a', 'a', 'b', 'b'],
            get_generated_test_attributes(suite, 'value'))

    def test_multiply_tests_no_scenarios(self):
        """Tests with no scenarios attribute aren't multiplied"""
        suite = TestLoader().suiteClass()
        multiply_tests_by_their_scenarios(self,
                                          suite)
        self.assertLength(1, list(iter_suite_tests(suite)))


class PretendVaryingTest(TestCase):

    scenarios = multiply_scenarios(
        vary_named_attribute('value'),
        vary_named_attribute('other'),
        )

    def test_nothing(self):
        """This test exists just so it can be multiplied"""
        pass
