# Path: jacquard/cli.py
# def main(args=sys.argv[1:], config=None):
#     """
#     Run as if from the command line, with the given arguments.
# 
#     If the arguments in `args` are not given they default to using `sys.argv`.
# 
#     Note that this function is permitted to raise SystemExit; users who do not
#     want exciting exiting behaviour should be prepared to catch this.
# 
#     If `config` is given, it is used in place of loading a configuration file.
#     """
#     parser = argument_parser()
#     options = parser.parse_args(args)
# 
#     config = _configure_process_and_load_config_from_options(
#         options=options, override_config=config
#     )
# 
#     # Run subcommand
#     with contextlib.suppress(KeyboardInterrupt):
#         try:
#             options.func(config, options)
#         except CommandError as exc:
#             (message,) = exc.args
#             print(message, file=sys.stderr)
#             exit(1)
# 
# Path: jacquard/config.py
# def load_config(source):
#     """
#     Load `Config` from file.
# 
#     `source` may be given either as a file-like or path-like object. In the
#     former case it should be opened for reading in text/unicode mode.
#     """
#     if hasattr(source, "read"):
#         return _load_config_from_fp(source)
#     else:
#         with pathlib.Path(source).open("r") as f:
#             return _load_config_from_fp(f)
# 
# Path: jacquard/service/wsgi.py
# def get_wsgi_app(config):
#     """Get the main WSGI handler, by config."""
#     endpoints = _get_endpoints(config)
#     url_map = _get_url_map(endpoints)
# 
#     def application(environ, start_response):
#         """WSGI callable."""
#         try:
#             urls = url_map.bind_to_environ(environ)
# 
#             LOGGER.debug(
#                 "%s %s", environ["REQUEST_METHOD"], environ["PATH_INFO"] or "/"
#             )
# 
#             def reverse(name, **kwargs):
#                 endpoint = endpoints[name]
#                 return urls.build(endpoint, values=kwargs)
# 
#             request = werkzeug.wrappers.Request(environ)
# 
#             endpoint, kwargs = urls.match()
# 
#             endpoint = endpoint.bind(reverse=reverse, request=request)
# 
#             response = endpoint.handle(**kwargs)
# 
#             encoded_response = (json.dumps(response) + "\n").encode("utf-8")
#             start_response(
#                 "200 OK",
#                 [
#                     ("Content-Type", "application/json"),
#                     ("Content-Length", str(len(encoded_response))),
#                 ],
#             )
#             return [encoded_response]
#         except werkzeug.exceptions.HTTPException as e:
#             return e(environ, start_response)
# 
#     return application
# 
# 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))


import io
import os
import shlex
import pathlib
import datetime
import textwrap
import contextlib
import unittest.mock
import yaml
import pytest
import dateutil.tz
import werkzeug.test
from jacquard.cli import main
from jacquard.config import load_config
from jacquard.service import get_wsgi_app
from jacquard.directory.base import UserEntry
from jacquard.directory.dummy import DummyDirectory
        )


@contextlib.contextmanager
def _temporary_working_directory(pwd):
    new_pwd = str(pwd)
    old_pwd = os.getcwd()
    os.chdir(new_pwd)
    try:
        yield
    finally:
        os.chdir(old_pwd)


@pytest.mark.parametrize(
    "test_file", [x.name for x in INTEGRATION_TESTS_ROOT.glob("*.yaml")]
)
def test_integration(test_file):
    with (INTEGRATION_TESTS_ROOT / test_file).open("r") as f:
        test_config = yaml.safe_load(f)

    config = load_config(io.StringIO(TEST_CONFIG))
    config = unittest.mock.Mock(wraps=config)
    config.directory = DummyDirectory(
        users=(
            UserEntry(
                id="1",
                join_date=datetime.datetime(2017, 1, 1, tzinfo=dateutil.tz.tzutc()),
                tags=(),
            ),

# Path: jacquard/cli.py
# def main(args=sys.argv[1:], config=None):
#     """
#     Run as if from the command line, with the given arguments.
# 
#     If the arguments in `args` are not given they default to using `sys.argv`.
# 
#     Note that this function is permitted to raise SystemExit; users who do not
#     want exciting exiting behaviour should be prepared to catch this.
# 
#     If `config` is given, it is used in place of loading a configuration file.
#     """
#     parser = argument_parser()
#     options = parser.parse_args(args)
# 
#     config = _configure_process_and_load_config_from_options(
#         options=options, override_config=config
#     )
# 
#     # Run subcommand
#     with contextlib.suppress(KeyboardInterrupt):
#         try:
#             options.func(config, options)
#         except CommandError as exc:
#             (message,) = exc.args
#             print(message, file=sys.stderr)
#             exit(1)
# 
# Path: jacquard/config.py
# def load_config(source):
#     """
#     Load `Config` from file.
# 
#     `source` may be given either as a file-like or path-like object. In the
#     former case it should be opened for reading in text/unicode mode.
#     """
#     if hasattr(source, "read"):
#         return _load_config_from_fp(source)
#     else:
#         with pathlib.Path(source).open("r") as f:
#             return _load_config_from_fp(f)
# 
# Path: jacquard/service/wsgi.py
# def get_wsgi_app(config):
#     """Get the main WSGI handler, by config."""
#     endpoints = _get_endpoints(config)
#     url_map = _get_url_map(endpoints)
# 
#     def application(environ, start_response):
#         """WSGI callable."""
#         try:
#             urls = url_map.bind_to_environ(environ)
# 
#             LOGGER.debug(
#                 "%s %s", environ["REQUEST_METHOD"], environ["PATH_INFO"] or "/"
#             )
# 
#             def reverse(name, **kwargs):
#                 endpoint = endpoints[name]
#                 return urls.build(endpoint, values=kwargs)
# 
#             request = werkzeug.wrappers.Request(environ)
# 
#             endpoint, kwargs = urls.match()
# 
#             endpoint = endpoint.bind(reverse=reverse, request=request)
# 
#             response = endpoint.handle(**kwargs)
# 
#             encoded_response = (json.dumps(response) + "\n").encode("utf-8")
#             start_response(
#                 "200 OK",
#                 [
#                     ("Content-Type", "application/json"),
#                     ("Content-Length", str(len(encoded_response))),
#                 ],
#             )
#             return [encoded_response]
#         except werkzeug.exceptions.HTTPException as e:
#             return e(environ, start_response)
# 
#     return application
# 
# 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/tests/test_integration.py
import io
import os
import shlex
import pathlib
import datetime
import textwrap
import contextlib
import unittest.mock
import yaml
import pytest
import dateutil.tz
import werkzeug.test
from jacquard.cli import main
from jacquard.config import load_config
from jacquard.service import get_wsgi_app
from jacquard.directory.base import UserEntry
from jacquard.directory.dummy import DummyDirectory

        )


@contextlib.contextmanager
def _temporary_working_directory(pwd):
    new_pwd = str(pwd)
    old_pwd = os.getcwd()
    os.chdir(new_pwd)
    try:
        yield
    finally:
        os.chdir(old_pwd)


@pytest.mark.parametrize(
    "test_file", [x.name for x in INTEGRATION_TESTS_ROOT.glob("*.yaml")]
)
def test_integration(test_file):
    with (INTEGRATION_TESTS_ROOT / test_file).open("r") as f:
        test_config = yaml.safe_load(f)

    config = load_config(io.StringIO(TEST_CONFIG))
    config = unittest.mock.Mock(wraps=config)
    config.directory = DummyDirectory(
        users=(
            UserEntry(
                id="1",
                join_date=datetime.datetime(2017, 1, 1, tzinfo=dateutil.tz.tzutc()),
                tags=(),
            ),

            UserEntry(