"""
Test case which exercises webcolors' conversion functions across all 16,777,216
possible hexadecimal values and all 16,777,216 possible integer rgb() triplet values.

You should not ever need to run this test; it is not part of the normal unit-test suite,
and is used only as a final check when preparing a new release of webcolors.

Because it generates each of the nearly 17 million color values multiple times, this
test case takes some time to run and consumes most or all available CPU while
running. As a consolation, it is somewhat efficient with respect to memory.

Due to the inherent imprecision of floating-point percentage values, and the fact that
the legal (with respect to the CSS standards) set of percentage rgb() triplets is
uncountably infinite, percentage rgb() triplets are not exhaustively tested here, and
the normal test suite is used to ensure correctness of the conversion functions for
those values.

The only test performed here for percentage rgb() triplets is to ensure that converting
an integer rgb() triplet to percentage and back returns the original integer values, for
consistency.

"""

# SPDX-License-Identifier: BSD-3-Clause

import unittest

import webcolors


def hex_colors():
    """
    Generator which yields all 2**24 hexadecimal color values, in order starting
    from #000000.

    """
    for i in range(16777217):
        yield f"#{i:06x}"


def int_colors():
    """
    Generator which yields all 2**24 integer rgb() triplets, in order starting from
    (0,0,0).

    """
    red_counter = tuple(range(256))
    green_counter = tuple(range(256))
    blue_counter = tuple(range(256))
    for red_value in red_counter:
        for green_value in green_counter:
            for blue_value in blue_counter:
                yield (red_value, green_value, blue_value)


class FullColorTest(unittest.TestCase):
    """
    Exercise color conversion on all testable values.

    """

    def test_full_colors(self):
        """
        Test conversion between hexadecimal and integer rgb() for
        all 2**24 possible values.

        """
        for hex_color, int_triplet in zip(hex_colors(), int_colors()):
            assert int_triplet == webcolors.hex_to_rgb(hex_color)
            assert hex_color == webcolors.rgb_to_hex(int_triplet)

    def test_triplet_conversion(self):
        """
        Test conversion between integer and percentage rgb() as fully as possible.

        Because exhaustive testing is not possible (the set of valid percentgae rgb()
        triplets is uncountably infinite), this test ensures that for each of the 2**24
        possible integer triplets, conversion to percentage and back gives the starting
        value.

        """
        for int_triplet in int_colors():
            conversion = webcolors.rgb_percent_to_rgb(
                webcolors.rgb_to_rgb_percent(int_triplet)
            )
            assert int_triplet == conversion


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