# Path: meta_package_manager/pool.py
# ALL_MANAGER_IDS = tuple(sorted(pool()))
# 
# @cached(LRI(max_size=1))
# def pool():
#     """Search for package manager definitions locally and store them into an
#     internal register.
# 
#     Is considered valid package manager, definitions classes which:
#         1 - are located in the `managers` subfolder, and
#         2 - are sub-classes of PackageManager, and
#         3 - are not virtual (i.e. have a non null `cli_names` property).
#     """
#     register = {}
# 
#     for py_file in Path(__file__).parent.joinpath(MANAGER_SUBFOLDER).glob("*.py"):
#         logger.debug(f"Search manager definitions in {py_file}")
#         module = import_module(
#             f".{MANAGER_SUBFOLDER}.{py_file.stem}", package=__package__
#         )
# 
#         for _, klass in inspect.getmembers(module, inspect.isclass):
#             if issubclass(klass, PackageManager) and not klass.virtual:
#                 logger.debug(f"Found {klass!r}")
#                 manager = klass()
#                 register[manager.id] = manager
#             else:
#                 logger.debug(f"{klass!r} is not a valid manager definition")
# 
#     return register
# 
# Path: meta_package_manager/version.py
# class TokenizedString:
# 
#     """Tokenize a string for user-friendly sorting.
# 
#     Essentially a wrapper around a tuple of `Token` instances.
#     """
# 
#     separator = None
#     string = None
#     tokens = ()
# 
#     def __hash__(self):
#         """A `TokenizedString` is made unique by its original string and tuple
#         of parsed tokens."""
#         return hash((self.string, self.separator, self.tokens))
# 
#     def __new__(cls, value, *args, **kwargs):
#         """Return same object if a TokenizedString parameter is used at
#         instanciation.
#         """
#         if isinstance(value, TokenizedString):
#             return value
#         return super().__new__(cls)
# 
#     def __init__(self, value, separator="-"):
#         if isinstance(value, TokenizedString):
#             # Skip initialization for instance of the class.
#             return
#         if isinstance(value, int):
#             self.string = str(value)
#         elif isinstance(value, str):
#             self.string = value.strip()
#         else:
#             raise TypeError(f"{type(value)} not supported")
#         self.tokens = tuple(self.tokenize(self.string))
#         self.separator = separator
# 
#     def __repr__(self):
#         return f"<TokenizedString {self.string} => {self.tokens}>"
# 
#     def __str__(self):
#         return self.string
# 
#     def pretty_print(self):
#         return self.separator.join(map(str, self.tokens))
# 
#     @classmethod
#     def tokenize(cls, string):
#         """Tokenize a string: ignore case and split at each non-alphanumeric
#         characters.
# 
#         Returns a tuple of Token instances. Which allows for comparison between
#         strings and integers. That way we get natural, user-friendly sorting of
#         version numbers. That we can get with simple Python, see:
# 
#             >>> '2019.0.1' > '9.3'
#             False
#             >>> ('2019', '0', '1') > ('9', '3')
#             False
#             >>> (2019, 0, 1) > (9, 3)
#             True
#         """
#         normalized_str = strutils.asciify(string).lower().decode()
# 
#         for segment in ALNUM_EXTRACTOR.split(normalized_str):
#             if segment.isalnum():
#                 yield Token(segment)
# 
#     """ TokenizedString can be compared as tuples. """
# 
#     def __iter__(self):
#         """`TokenizedString` essentially are a wrapper around a tuple of
#         `Token`.
#         """
#         return iter(self.tokens)
# 
#     def __eq__(self, other):
#         if isinstance(other, (TokenizedString, tuple)):
#             return tuple(self) == tuple(other)
# 
#     def __ne__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) != tuple(other)
# 
#     def __gt__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) > tuple(other)
# 
#     def __lt__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) < tuple(other)
# 
#     def __ge__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) >= tuple(other)
# 
#     def __le__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) <= tuple(other)


import re
import pytest
from operator import attrgetter
from pathlib import Path, PurePath
from string import ascii_letters, ascii_lowercase, digits
from types import MethodType
from click_extra.platform import OS_DEFINITIONS
from ..pool import ALL_MANAGER_IDS, pool
from ..version import TokenizedString
# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
# All Rights Reserved.
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.




""" Test the structure, data and types returned by all package managers.

This test suite try to automate most of the basic reviewing work for the addition of
new package manager definitions.
"""

# Parametrization decorators.
all_managers = pytest.mark.parametrize("manager", pool().values(), ids=attrgetter("id"))



# Path: meta_package_manager/pool.py
# ALL_MANAGER_IDS = tuple(sorted(pool()))
# 
# @cached(LRI(max_size=1))
# def pool():
#     """Search for package manager definitions locally and store them into an
#     internal register.
# 
#     Is considered valid package manager, definitions classes which:
#         1 - are located in the `managers` subfolder, and
#         2 - are sub-classes of PackageManager, and
#         3 - are not virtual (i.e. have a non null `cli_names` property).
#     """
#     register = {}
# 
#     for py_file in Path(__file__).parent.joinpath(MANAGER_SUBFOLDER).glob("*.py"):
#         logger.debug(f"Search manager definitions in {py_file}")
#         module = import_module(
#             f".{MANAGER_SUBFOLDER}.{py_file.stem}", package=__package__
#         )
# 
#         for _, klass in inspect.getmembers(module, inspect.isclass):
#             if issubclass(klass, PackageManager) and not klass.virtual:
#                 logger.debug(f"Found {klass!r}")
#                 manager = klass()
#                 register[manager.id] = manager
#             else:
#                 logger.debug(f"{klass!r} is not a valid manager definition")
# 
#     return register
# 
# Path: meta_package_manager/version.py
# class TokenizedString:
# 
#     """Tokenize a string for user-friendly sorting.
# 
#     Essentially a wrapper around a tuple of `Token` instances.
#     """
# 
#     separator = None
#     string = None
#     tokens = ()
# 
#     def __hash__(self):
#         """A `TokenizedString` is made unique by its original string and tuple
#         of parsed tokens."""
#         return hash((self.string, self.separator, self.tokens))
# 
#     def __new__(cls, value, *args, **kwargs):
#         """Return same object if a TokenizedString parameter is used at
#         instanciation.
#         """
#         if isinstance(value, TokenizedString):
#             return value
#         return super().__new__(cls)
# 
#     def __init__(self, value, separator="-"):
#         if isinstance(value, TokenizedString):
#             # Skip initialization for instance of the class.
#             return
#         if isinstance(value, int):
#             self.string = str(value)
#         elif isinstance(value, str):
#             self.string = value.strip()
#         else:
#             raise TypeError(f"{type(value)} not supported")
#         self.tokens = tuple(self.tokenize(self.string))
#         self.separator = separator
# 
#     def __repr__(self):
#         return f"<TokenizedString {self.string} => {self.tokens}>"
# 
#     def __str__(self):
#         return self.string
# 
#     def pretty_print(self):
#         return self.separator.join(map(str, self.tokens))
# 
#     @classmethod
#     def tokenize(cls, string):
#         """Tokenize a string: ignore case and split at each non-alphanumeric
#         characters.
# 
#         Returns a tuple of Token instances. Which allows for comparison between
#         strings and integers. That way we get natural, user-friendly sorting of
#         version numbers. That we can get with simple Python, see:
# 
#             >>> '2019.0.1' > '9.3'
#             False
#             >>> ('2019', '0', '1') > ('9', '3')
#             False
#             >>> (2019, 0, 1) > (9, 3)
#             True
#         """
#         normalized_str = strutils.asciify(string).lower().decode()
# 
#         for segment in ALNUM_EXTRACTOR.split(normalized_str):
#             if segment.isalnum():
#                 yield Token(segment)
# 
#     """ TokenizedString can be compared as tuples. """
# 
#     def __iter__(self):
#         """`TokenizedString` essentially are a wrapper around a tuple of
#         `Token`.
#         """
#         return iter(self.tokens)
# 
#     def __eq__(self, other):
#         if isinstance(other, (TokenizedString, tuple)):
#             return tuple(self) == tuple(other)
# 
#     def __ne__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) != tuple(other)
# 
#     def __gt__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) > tuple(other)
# 
#     def __lt__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) < tuple(other)
# 
#     def __ge__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) >= tuple(other)
# 
#     def __le__(self, other):
#         if isinstance(other, TokenizedString):
#             return tuple(self) <= tuple(other)


# Path: meta_package_manager/tests/test_managers.py
import re
import pytest
from operator import attrgetter
from pathlib import Path, PurePath
from string import ascii_letters, ascii_lowercase, digits
from types import MethodType
from click_extra.platform import OS_DEFINITIONS
from ..pool import ALL_MANAGER_IDS, pool
from ..version import TokenizedString

# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
# All Rights Reserved.
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.




""" Test the structure, data and types returned by all package managers.

This test suite try to automate most of the basic reviewing work for the addition of
new package manager definitions.
"""

# Parametrization decorators.
all_managers = pytest.mark.parametrize("manager", pool().values(), ids=attrgetter("id"))



@pytest.mark.parametrize("manager_id,manager", pool().items())