# Path: jacquard/directory/base.py
# class Directory(metaclass=abc.ABCMeta):
#     def __init__(self, **kwargs):
#     def from_configuration(cls, config, options):
#     def lookup(self, user_id):
# 
# Path: jacquard/directory/dummy.py
# class DummyDirectory(Directory):
#     """Dummy user directory."""
# 
#     def __init__(self, users=()):
#         """
#         Initialise.
# 
#         If `users` is given it should be an iterable of `UserEntry` instances.
#         This is likely only to be useful in tests, given that one cannot
#         construct `UserEntry` instances in a config file.
#         """
#         self.users = {str(x.id): x for x in users}
# 
#     def lookup(self, user_id):
#         """Look up user by ID."""
#         return self.users.get(str(user_id))
# 
# Path: jacquard/directory/union.py
# class UnionDirectory(Directory):
#     """A union of zero or more directories."""
# 
#     def __init__(self, subdirectories):
#         """
#         Initializer.
# 
#         This is used with an iterable of `Directory` instances to construct
#         directly: `from_configuration` is used for the format as found in
#         `jacquard.cfg` files.
#         """
#         self._subdirectories = list(subdirectories)
# 
#     @classmethod
#     def _construct_subdirectories_from_config(cls, config, options):
#         # The configuration format is config_key[index] = value.
#         # We extract this in three logical stages:
#         # (1) Calculate the maximum index,
#         # (2) Construct the dict of indices -> configurations,
#         # (3) Call `open_directory` on each.
#         # For the sake of simplicitly steps (1) and (2) are combined using
#         # some defaultdict trickery.
#         sub_configurations = collections.defaultdict(dict)
# 
#         for key, value in options.items():
#             match = INDEXED_KEY_RE.match(key)
# 
#             if match is None:
#                 continue
# 
#             config_key = match.group(1)
#             config_index = int(match.group(2))
# 
#             sub_configurations[config_index][config_key] = value
# 
#         try:
#             maximum_index = max(sub_configurations.keys())
#         except ValueError:
#             # No configurations at all: this is a null union
#             return
# 
#         for subdirectory_index in range(maximum_index + 1):
#             sub_configuration = sub_configurations[subdirectory_index]
#             engine = sub_configuration.pop("engine")
#             yield open_directory(config, engine, sub_configuration)
# 
#     @classmethod
#     def from_configuration(cls, config, options):
#         """
#         Build from the configuration format.
# 
#         This lists configuration for the subdirectories with square bracket
#         indexing. For example:
# 
#             [directory]
#             engine = union
#             engine[0] = my_engine
#             param[0] = my_param
#             engine[1] = django
#             url[1] = postgresql:///my_django_db
#         """
#         return cls(cls._construct_subdirectories_from_config(config, options))
# 
#     def lookup(self, user_id):
#         """
#         Look up user by ID.
# 
#         For missing users this must return None, otherwise it must return a
#         corresponding `UserEntry`.
# 
#         Where a user is present in multiple subdirectories, the first is
#         taken.
#         """
#         for subdirectory in self._subdirectories:
#             user_entry = subdirectory.lookup(user_id)
# 
#             if user_entry is not None:
#                 return user_entry
# 
#         return None


from unittest import mock
from jacquard.directory.base import UserEntry
from jacquard.directory.dummy import DummyDirectory
from jacquard.directory.union import UnionDirectory



def test_union_returns_results_from_first_directory():
    user_1 = UserEntry(id=1, join_date=None, tags=())

    dir1 = DummyDirectory(users=[user_1])

# Path: jacquard/directory/base.py
# class Directory(metaclass=abc.ABCMeta):
#     def __init__(self, **kwargs):
#     def from_configuration(cls, config, options):
#     def lookup(self, user_id):
# 
# Path: jacquard/directory/dummy.py
# class DummyDirectory(Directory):
#     """Dummy user directory."""
# 
#     def __init__(self, users=()):
#         """
#         Initialise.
# 
#         If `users` is given it should be an iterable of `UserEntry` instances.
#         This is likely only to be useful in tests, given that one cannot
#         construct `UserEntry` instances in a config file.
#         """
#         self.users = {str(x.id): x for x in users}
# 
#     def lookup(self, user_id):
#         """Look up user by ID."""
#         return self.users.get(str(user_id))
# 
# Path: jacquard/directory/union.py
# class UnionDirectory(Directory):
#     """A union of zero or more directories."""
# 
#     def __init__(self, subdirectories):
#         """
#         Initializer.
# 
#         This is used with an iterable of `Directory` instances to construct
#         directly: `from_configuration` is used for the format as found in
#         `jacquard.cfg` files.
#         """
#         self._subdirectories = list(subdirectories)
# 
#     @classmethod
#     def _construct_subdirectories_from_config(cls, config, options):
#         # The configuration format is config_key[index] = value.
#         # We extract this in three logical stages:
#         # (1) Calculate the maximum index,
#         # (2) Construct the dict of indices -> configurations,
#         # (3) Call `open_directory` on each.
#         # For the sake of simplicitly steps (1) and (2) are combined using
#         # some defaultdict trickery.
#         sub_configurations = collections.defaultdict(dict)
# 
#         for key, value in options.items():
#             match = INDEXED_KEY_RE.match(key)
# 
#             if match is None:
#                 continue
# 
#             config_key = match.group(1)
#             config_index = int(match.group(2))
# 
#             sub_configurations[config_index][config_key] = value
# 
#         try:
#             maximum_index = max(sub_configurations.keys())
#         except ValueError:
#             # No configurations at all: this is a null union
#             return
# 
#         for subdirectory_index in range(maximum_index + 1):
#             sub_configuration = sub_configurations[subdirectory_index]
#             engine = sub_configuration.pop("engine")
#             yield open_directory(config, engine, sub_configuration)
# 
#     @classmethod
#     def from_configuration(cls, config, options):
#         """
#         Build from the configuration format.
# 
#         This lists configuration for the subdirectories with square bracket
#         indexing. For example:
# 
#             [directory]
#             engine = union
#             engine[0] = my_engine
#             param[0] = my_param
#             engine[1] = django
#             url[1] = postgresql:///my_django_db
#         """
#         return cls(cls._construct_subdirectories_from_config(config, options))
# 
#     def lookup(self, user_id):
#         """
#         Look up user by ID.
# 
#         For missing users this must return None, otherwise it must return a
#         corresponding `UserEntry`.
# 
#         Where a user is present in multiple subdirectories, the first is
#         taken.
#         """
#         for subdirectory in self._subdirectories:
#             user_entry = subdirectory.lookup(user_id)
# 
#             if user_entry is not None:
#                 return user_entry
# 
#         return None


# Path: jacquard/directory/tests/test_union.py
from unittest import mock
from jacquard.directory.base import UserEntry
from jacquard.directory.dummy import DummyDirectory
from jacquard.directory.union import UnionDirectory




def test_union_returns_results_from_first_directory():
    user_1 = UserEntry(id=1, join_date=None, tags=())

    dir1 = DummyDirectory(users=[user_1])

    dir2 = DummyDirectory(users=[])