Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pytest-httpserver for 
openSUSE:Factory checked in at 2023-05-24 20:21:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-httpserver (Old)
 and      /work/SRC/openSUSE:Factory/.python-pytest-httpserver.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pytest-httpserver"

Wed May 24 20:21:39 2023 rev:11 rq:1088466 version:1.0.7

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-pytest-httpserver/python-pytest-httpserver.changes
        2023-05-09 13:06:32.352735776 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pytest-httpserver.new.1533/python-pytest-httpserver.changes
      2023-05-24 20:21:47.471975183 +0200
@@ -1,0 +2,25 @@
+Mon May 22 21:17:53 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 1.0.7:
+  * With werkzeug 2.3.x the headers type has been updated to not
+    allow integers as header values. This restriction followed up
+    in pytest-httpserver.
+  * Python versions earlier than 3.8 have been deprecated in
+    order to support the latest werkzeug.
+  * Type hinting for header_value_matcher has been fixed. From
+    now, specifying a callable as ``Callable[[str,
+    Optional[str], str], bool]`` will be accepted also. 
+    Providing a ``HeaderValueMatcher`` object will be also
+    accepted as before, as it provides the same callable signature
+  * Fix Werkzeug deprecation warning about
+    ``parse_authorization_header`` call.
+  * Replace ``parse_authorization_header`` with
+    ``Authorization.from_header`` as suggested. This fix should
+    not introduce any functional change for the users.
+  * Fix Werkzeug deprecation warning about
+    ``werkzeug.urls.url_decode`` call. This call has been changed
+    to ``urllib.parse.parse_qsl`` in the implementation.
+    This fix should not introduce any functional change for the
+    users.
+
+-------------------------------------------------------------------

Old:
----
  pytest_httpserver-1.0.6.tar.gz

New:
----
  pytest_httpserver-1.0.7.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pytest-httpserver.spec ++++++
--- /var/tmp/diff_new_pack.NxByS2/_old  2023-05-24 20:21:48.435980931 +0200
+++ /var/tmp/diff_new_pack.NxByS2/_new  2023-05-24 20:21:48.443980979 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-pytest-httpserver
-Version:        1.0.6
+Version:        1.0.7
 Release:        0
 Summary:        A HTTP server for pytest
 License:        MIT

++++++ pytest_httpserver-1.0.6.tar.gz -> pytest_httpserver-1.0.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/CHANGES.rst 
new/pytest_httpserver-1.0.7/CHANGES.rst
--- old/pytest_httpserver-1.0.6/CHANGES.rst     2022-09-12 09:25:14.312314500 
+0200
+++ new/pytest_httpserver-1.0.7/CHANGES.rst     2023-05-16 21:40:52.284019700 
+0200
@@ -2,6 +2,50 @@
 Release Notes
 =============
 
+.. _Release Notes_1.0.7:
+
+1.0.7
+=====
+
+.. _Release Notes_1.0.7_Upgrade Notes:
+
+Upgrade Notes
+-------------
+
+- With werkzeug 2.3.x the headers type has been updated to not allow integers 
as header values. This restriction followed up in pytest-httpserver.
+
+
+.. _Release Notes_1.0.7_Deprecation Notes:
+
+Deprecation Notes
+-----------------
+
+- Python versions earlier than 3.8 have been deprecated in order to support
+  the latest werkzeug. Users using 3.7 or earlier python may use
+  pytest-httpserver with earlier werkzeug versions but tests are no longer run
+  for these python versions.
+
+
+.. _Release Notes_1.0.7_Bug Fixes:
+
+Bug Fixes
+---------
+
+- Type hinting for header_value_matcher has been fixed. From now, specifying a
+  callable as ``Callable[[str, Optional[str], str], bool]`` will be accepted
+  also. Providing a ``HeaderValueMatcher`` object will be also accepted as
+  before, as it provides the same callable signature.
+
+- Fix Werkzeug deprecation warning about ``parse_authorization_header`` call.
+  Replace ``parse_authorization_header`` with ``Authorization.from_header`` as
+  suggested. This fix should not introduce any functional change for the
+  users.
+
+- Fix Werkzeug deprecation warning about ``werkzeug.urls.url_decode`` call. 
This
+  call has been changed to ``urllib.parse.parse_qsl`` in the implementation.
+  This fix should not introduce any functional change for the users.
+
+
 .. _Release Notes_1.0.6:
 
 1.0.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/CONTRIBUTION.md 
new/pytest_httpserver-1.0.7/CONTRIBUTION.md
--- old/pytest_httpserver-1.0.6/CONTRIBUTION.md 2022-09-03 10:53:55.022256900 
+0200
+++ new/pytest_httpserver-1.0.7/CONTRIBUTION.md 2023-05-16 20:58:37.762110000 
+0200
@@ -20,8 +20,9 @@
 
 There are a few rules you are kindly asked to accept:
 
-* Coding style is checked by `pre-commit`. You can run `make precommit` before 
proceeding
-  with the PR.
+* Coding style is checked by `pre-commit`. You can run `make precommit` before
+  proceeding with the PR. To install the pre-commit hooks to your git (so it
+  will be run for each commit), run `pre-commit install`.
 
 * Tests should be written for the new code. If there's a complex logic
   implemented, it should be tested on different valid and invalid inputs and
@@ -41,11 +42,15 @@
 * You can let your IDE of your choice to use the `.venv/bin/python` 
interpreter,
   so it will know all the dependencies.
 
-* running tests on the localhost can be done by issuing `make quick-test`. It 
is
-  "quick" because it tests the software with only one interpreter. Note that 
the
+* running tests on the localhost can be done by issuing `make test`. Note that 
the
   library can be used by many supported interpreters and unless it is 
absolutely
   required, we don't want to drop support.
 
+* running tests on multiple versions of interpreter locally can be done by
+  `tox`. Keep in mind that the CI job uses github actions with caching for
+  effective use, and `tox` is provided for the developers only.
+
+
 ## More technical details
 
 * Release notes must be written for significant changes. This is done by
@@ -56,3 +61,12 @@
   docstrings, but if the PR changes the code and the way of working
   conceptually, the main documentation (located in the doc directory) needs to
   be updated and extended.
+
+* nix files are provided on a best-effort basis. `tox.nix` can be used to run
+  `tox`, `shell.nix` can be used instead of poetry for development. No tests
+  have been written for these (yet!), so they may be out of sync occasionally.
+
+* to release a new version, you can use the `scripts/release.py` script to make
+  the wheels and sdist, generate the changelog, and tag the commit. This tool
+  won't upload the artifacts as they need to be checked manually (by installing
+  the wheel to a new venv, for example).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/PKG-INFO 
new/pytest_httpserver-1.0.7/PKG-INFO
--- old/pytest_httpserver-1.0.6/PKG-INFO        1970-01-01 01:00:00.000000000 
+0100
+++ new/pytest_httpserver-1.0.7/PKG-INFO        1970-01-01 01:00:00.000000000 
+0100
@@ -1,22 +1,22 @@
 Metadata-Version: 2.1
 Name: pytest-httpserver
-Version: 1.0.6
+Version: 1.0.7
 Summary: pytest-httpserver is a httpserver for pytest
 Home-page: https://github.com/csernazs/pytest-httpserver
 License: MIT
 Author: Zsolt Cserna
 Author-email: cserna.zs...@gmail.com
-Requires-Python: >=3.7,<4.0
+Requires-Python: >=3.8,<4.0
 Classifier: Development Status :: 3 - Alpha
 Classifier: Framework :: Pytest
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Requires-Dist: Werkzeug (>=2.0.0)
 Project-URL: Bug Tracker, https://github.com/csernazs/pytest-httpserver/issues
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/doc/background.rst 
new/pytest_httpserver-1.0.7/doc/background.rst
--- old/pytest_httpserver-1.0.6/doc/background.rst      2022-07-13 
18:49:54.026996000 +0200
+++ new/pytest_httpserver-1.0.7/doc/background.rst      2023-05-16 
21:40:52.284019700 +0200
@@ -40,24 +40,15 @@
 
 Example:
 
-.. code-block:: python
-
-    def test_query_params(httpserver):
-        httpserver.expect_request("/foo", query_string={"user": 
"user1"}).respond_with_data(
-            "OK"
-        )
+.. literalinclude :: ../tests/examples/test_example_query_params1.py
+   :language: python
 
 It is simple in the most simple cases, but once the expectation is more
 specific, the line can grow significantly, so here the user is expected to put
 the literals into variables:
 
-.. code-block:: python
-
-    def test_query_params(httpserver):
-        httpserver.expect_request("/foo", 
query_string=expected_query).respond_with_data(
-            "OK"
-        )
-
+.. literalinclude :: ../tests/examples/test_example_query_params2.py
+   :language: python
 
 If the user wants something more complex, classes are available for this which
 can be instantiated and then specified for the parameters normally accepting
@@ -176,12 +167,11 @@
 The library should be tested periodically on the supported versions.
 
 Dropping support for old python versions is possible if supporting would cause
-an issue or require extensive workaround. Currently, 3.4 is still supported by
-the library, however it is deprecated by PSF. As it causes no problems for
-*pytest-httpserver* (there's an additional requirement for this in the 
setup.py,
-but that's all), the support for this version will be maintained as long as
-possible. Once a new change is added to the library which require great effort
-to maintain compatibility with 3.4, the support for it will be dropped.
+an issue or require extensive workaround.
+
+Python support for a given version is also dropped if it is near to the end of
+support or when a dependency deprecates it - this is needed to move forward 
with
+the community in order to support the latest versions of the dependencies.
 
 
 Testing and coverage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/doc/conf.py 
new/pytest_httpserver-1.0.7/doc/conf.py
--- old/pytest_httpserver-1.0.6/doc/conf.py     2022-09-12 09:25:14.313314400 
+0200
+++ new/pytest_httpserver-1.0.7/doc/conf.py     2023-05-16 21:40:52.284019700 
+0200
@@ -66,7 +66,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = "1.0.6"
+version = "1.0.7"
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/doc/howto.rst 
new/pytest_httpserver-1.0.7/doc/howto.rst
--- old/pytest_httpserver-1.0.6/doc/howto.rst   2022-09-12 08:46:31.629976300 
+0200
+++ new/pytest_httpserver-1.0.7/doc/howto.rst   2023-05-16 20:58:37.763110000 
+0200
@@ -15,17 +15,13 @@
 To match query parameters, you must not included them to the URI, as this will
 not work:
 
-.. code-block:: python
-
-    def test_query_params(httpserver):
-        httpserver.expect_request("/foo?user=bar")  # never do this
+.. literalinclude :: ../tests/examples/test_howto_query_params_never_do_this.py
+   :language: python
 
 There's an explicit place where the query string should go:
 
-.. code-block:: python
-
-    def test_query_params(httpserver):
-        httpserver.expect_request("/foo", query_string="user=bar")
+.. literalinclude :: ../tests/examples/test_howto_query_params_proper_use.py
+   :language: python
 
 The ``query_string`` is the parameter which does not contain the leading
 question mark ``?``.
@@ -43,15 +39,9 @@
 strange but we wanted to keep API compatibility and this dict matching feature
 was added later).
 
-.. code-block:: python
-
-    def test_query_params(httpserver):
-        httpserver.expect_request(
-            "/foo", query_string={"user": "user1", "group": "group1"}
-        ).respond_with_data("OK")
 
-        assert requests.get("/foo?user=user1&group=group1").status_code == 200
-        assert requests.get("/foo?group=group1&user=user1").status_code == 200
+.. literalinclude :: ../tests/examples/test_howto_query_params_dict.py
+   :language: python
 
 In the example above, both requests pass the test as we specified the expected
 query string as a dictionary.
@@ -70,9 +60,8 @@
 If this is not desired, you can specify a regexp object (returned by the
 ``re.compile()`` call).
 
-.. code:: python
-
-    httpserver.expect_request(re.compile("^/foo"), method="GET")
+.. literalinclude :: ../tests/examples/test_howto_regexp.py
+   :language: python
 
 The above will match every URI starting with "/foo".
 
@@ -82,18 +71,9 @@
 string and should return a boolean value.
 
 
-.. code:: python
-
-    class PrefixMatch(URIPattern):
-        def __init__(self, prefix: str):
-            self.prefix = prefix
-
-        def match(self, uri):
-            return uri.startswith(self.prefix)
-
+.. literalinclude :: ../tests/examples/test_howto_url_matcher.py
+   :language: python
 
-    def test_uripattern_object(httpserver: HTTPServer):
-        
httpserver.expect_request(PrefixMatch("/foo")).respond_with_json({"foo": "bar"})
 
 Authentication
 --------------
@@ -121,50 +101,8 @@
 By default, pytest-httpserver includes an Authorization header parser so the
 order of the parameters in the ``Authorization`` header does not matter.
 
-.. code:: python
-
-    def test_authorization_headers(httpserver: HTTPServer):
-        headers_with_values_in_direct_order = {
-            "Authorization": (
-                'Digest username="Mufasa",'
-                'realm="testre...@host.com",'
-                'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",'
-                'uri="/dir/index.html",'
-                "qop=auth,"
-                "nc=00000001,"
-                'cnonce="0a4f113b",'
-                'response="6629fae49393a05397450978507c4ef1",'
-                'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
-            )
-        }
-        httpserver.expect_request(
-            uri="/", headers=headers_with_values_in_direct_order
-        ).respond_with_data("OK")
-        response = requests.get(
-            httpserver.url_for("/"), 
headers=headers_with_values_in_direct_order
-        )
-        assert response.status_code == 200
-        assert response.text == "OK"
-
-        headers_with_values_in_modified_order = {
-            "Authorization": (
-                "Digest qop=auth,"
-                'username="Mufasa",'
-                'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",'
-                'uri="/dir/index.html",'
-                "nc=00000001,"
-                'realm="testre...@host.com",'
-                'response="6629fae49393a05397450978507c4ef1",'
-                'cnonce="0a4f113b",'
-                'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
-            )
-        }
-        response = requests.get(
-            httpserver.url_for("/"), 
headers=headers_with_values_in_modified_order
-        )
-        assert response.status_code == 200
-        assert response.text == "OK"
-
+.. literalinclude :: ../tests/examples/test_howto_authorization_headers.py
+   :language: python
 
 JSON matching
 -------------
@@ -185,16 +123,8 @@
 
 Example:
 
-.. code:: python
-
-    def test_json_matcher(httpserver: HTTPServer):
-        httpserver.expect_request("/foo", json={"foo": 
"bar"}).respond_with_data(
-            "Hello world!"
-        )
-        resp = requests.get(httpserver.url_for("/foo"), json={"foo": "bar"})
-        assert resp.status_code == 200
-        assert resp.text == "Hello world!"
-
+.. literalinclude :: ../tests/examples/test_howto_json_matcher.py
+   :language: python
 
 .. note::
     JSON requests usually come with ``Content-Type: application/json`` header.
@@ -222,29 +152,8 @@
 
 You need to implement such a function and then use it:
 
-.. code:: python
-
-    def case_insensitive_matcher(header_name: str, actual: str, expected: str) 
-> bool:
-        if header_name == "X-Foo":
-            return actual.lower() == expected.lower()
-        else:
-            return actual == expected
-
-
-    def test_case_insensitive_matching(httpserver: HTTPServer):
-        httpserver.expect_request(
-            "/", header_value_matcher=case_insensitive_matcher, 
headers={"X-Foo": "bar"}
-        ).respond_with_data("OK")
-
-        assert (
-            requests.get(httpserver.url_for("/"), headers={"X-Foo": 
"bar"}).status_code
-            == 200
-        )
-        assert (
-            requests.get(httpserver.url_for("/"), headers={"X-Foo": 
"BAR"}).status_code
-            == 200
-        )
-
+.. literalinclude :: ../tests/examples/test_howto_case_insensitive_matcher.py
+   :language: python
 
 .. note::
     Header value matcher is the basis of the ``Authorization`` header parsing.
@@ -285,30 +194,8 @@
 In case you don't want to change the defaults, you can provide the
 ``HeaderValueMatcher`` object itself.
 
-.. code:: python
-
-    from pytest_httpserver import HeaderValueMatcher
-
-
-    def case_insensitive_compare(actual: str, expected: str) -> bool:
-        return actual.lower() == expected.lower()
-
-
-    def test_own_matcher_object(httpserver: HTTPServer):
-        matcher = HeaderValueMatcher({"X-Bar": case_insensitive_compare})
-
-        httpserver.expect_request(
-            "/", headers={"X-Bar": "bar"}, header_value_matcher=matcher
-        ).respond_with_data("OK")
-
-        assert (
-            requests.get(httpserver.url_for("/"), headers={"X-Bar": 
"bar"}).status_code
-            == 200
-        )
-        assert (
-            requests.get(httpserver.url_for("/"), headers={"X-Bar": 
"BAR"}).status_code
-            == 200
-        )
+.. literalinclude :: ../tests/examples/test_howto_header_value_matcher.py
+   :language: python
 
 Using custom request handler
 ----------------------------
@@ -316,18 +203,9 @@
 you can pass a function to the ``respond_with_handler`` function. This function
 will be called with a request object and it should return a Response object.
 
-.. code:: python
-
-    from werkzeug.wrappers import Request, Response
-    from random import randint
-
-
-    def test_expected_request_handler(httpserver: HTTPServer):
-        def handler(request: Request):
-            return Response(str(randint(1, 10)))
-
-        httpserver.expect_request("/foobar").respond_with_handler(handler)
 
+.. literalinclude :: ../tests/examples/test_howto_custom_handler.py
+   :language: python
 
 The above code implements a handler which returns a random number between 1 and
 10. Not particularly useful but shows that the handler can return any computed
@@ -344,57 +222,15 @@
 
 Two notable examples for this:
 
-.. code:: python
-
-    def test_check_assertions_raises_handler_assertions(httpserver: 
HTTPServer):
-        def handler(_):
-            assert 1 == 2
-
-        httpserver.expect_request("/foobar").respond_with_handler(handler)
-
-        requests.get(httpserver.url_for("/foobar"))
-
-        # if you leave this "with" statement out, check_assertions() will break
-        # the test by re-raising the assertion error caused by the handler
-        # pytest will pick this exception as it was happened in the main thread
-        with pytest.raises(AssertionError):
-            httpserver.check_assertions()
-
-        httpserver.check_handler_errors()
-
-
-    def test_check_handler_errors_raises_handler_error(httpserver: HTTPServer):
-        def handler(_):
-            raise ValueError("should be propagated")
-
-        httpserver.expect_request("/foobar").respond_with_handler(handler)
-
-        requests.get(httpserver.url_for("/foobar"))
-
-        httpserver.check_assertions()
-
-        # if you leave this "with" statement out, check_handler_errors() will
-        # break the test with the original exception
-        with pytest.raises(ValueError):
-            httpserver.check_handler_errors()
-
+.. literalinclude :: ../tests/examples/test_howto_check_handler_errors.py
+   :language: python
 
 If you want to call both methods (``check_handler_errors()`` and
 ``check_assertions()``) you can call the ``check()`` method, which will call
 these.
 
-
-.. code:: python
-
-    def test_check_assertions(httpserver: HTTPServer):
-        def handler(_):
-            assert 1 == 2
-
-        httpserver.expect_request("/foobar").respond_with_handler(handler)
-
-        requests.get(httpserver.url_for("/foobar"))
-
-        httpserver.check()
+.. literalinclude :: ../tests/examples/test_howto_check.py
+   :language: python
 
 .. note::
     The scope of the errors checked by the ``check()`` method may
@@ -478,24 +314,8 @@
 
 Last, you need to assert on the ``result`` attribute of the context object.
 
-.. code-block:: python
-
-    def test_wait_success(httpserver: HTTPServer):
-        waiting_timeout = 0.1
-
-        with httpserver.wait(stop_on_nohandler=False, timeout=waiting_timeout) 
as waiting:
-            requests.get(httpserver.url_for("/foobar"))
-            httpserver.expect_oneshot_request("/foobar").respond_with_data("OK 
foobar")
-            requests.get(httpserver.url_for("/foobar"))
-        assert waiting.result
-
-        httpserver.expect_oneshot_request("/foobar").respond_with_data("OK 
foobar")
-        httpserver.expect_oneshot_request("/foobaz").respond_with_data("OK 
foobaz")
-        with httpserver.wait(timeout=waiting_timeout) as waiting:
-            requests.get(httpserver.url_for("/foobar"))
-            requests.get(httpserver.url_for("/foobaz"))
-        assert waiting.result
-
+.. literalinclude :: ../tests/examples/test_howto_wait_success.py
+   :language: python
 
 In the above code, all the request.get() calls could be in a different thread,
 eg. running in parallel, but the exit condition of the context object is to 
wait
@@ -509,19 +329,10 @@
 by peer* or *Connection refused*, you can simply do it by connecting to a 
random
 port number where no service is listening:
 
-.. code-block:: python
-
-    import pytest
-    import requests
-
-
-    def test_connection_refused():
-        # assumes that there's no server listening at localhost:1234
-        with pytest.raises(requests.exceptions.ConnectionError):
-            requests.get("http://localhost:1234";)
-
+.. literalinclude :: ../tests/examples/test_howto_timeout_requests.py
+   :language: python
 
-However connecting to the port where the httpserver had been started will still
+However, connecting to the port where the httpserver had been started will 
still
 succeed as the server is running continuously. This is working by design as
 starting/stopping the server is costly.
 
@@ -530,6 +341,7 @@
     import pytest
     import requests
 
+
     # setting a fixed port for httpserver
     @pytest.fixture(scope="session")
     def httpserver_listen_address():
@@ -607,20 +419,46 @@
 
 
     @pytest.fixture(scope="session")
-    def localhost_cert(ca):
-        return ca.issue_cert("localhost")
+    def httpserver_ssl_context(ca):
+        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+        localhost_cert = ca.issue_cert("localhost")
+        localhost_cert.configure_cert(context)
+        return context
 
 
     @pytest.fixture(scope="session")
-    def httpserver_ssl_context(localhost_cert):
-        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+    def httpclient_ssl_context(ca):
+        with ca.cert_pem.tempfile() as ca_temp_path:
+            return ssl.create_default_context(cafile=ca_temp_path)
 
-        crt = localhost_cert.cert_chain_pems[0]
-        key = localhost_cert.private_key_pem
-        with crt.tempfile() as crt_file, key.tempfile() as key_file:
-            context.load_cert_chain(crt_file, key_file)
 
-        return context
+    @pytest.mark.asyncio
+    async def test_aiohttp(httpserver, httpclient_ssl_context):
+        import aiohttp
+
+        httpserver.expect_request("/").respond_with_data("hello world!")
+        connector = aiohttp.TCPConnector(ssl=httpclient_ssl_context)
+        async with aiohttp.ClientSession(connector=connector) as session:
+            async with session.get(httpserver.url_for("/")) as result:
+                assert (await result.text()) == "hello world!"
+
+
+    def test_requests(httpserver, ca):
+        import requests
+
+        httpserver.expect_request("/").respond_with_data("hello world!")
+        with ca.cert_pem.tempfile() as ca_temp_path:
+            result = requests.get(httpserver.url_for("/"), verify=ca_temp_path)
+        assert result.text == "hello world!"
+
+
+    def test_httpx(httpserver, httpclient_ssl_context):
+        import httpx
+
+        httpserver.expect_request("/").respond_with_data("hello world!")
+        result = httpx.get(httpserver.url_for("/"), 
verify=httpclient_ssl_context)
+        assert result.text == "hello world!"
+
 
 Using httpserver on a dual-stack (IPv4 and IPv6) system
 -------------------------------------------------------
@@ -672,5 +510,5 @@
 
 Example:
 
-.. literalinclude :: ../tests/test_blocking_httpserver_howto.py
+.. literalinclude :: ../tests/examples/test_example_blocking_httpserver.py
    :language: python
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/doc/tutorial.rst 
new/pytest_httpserver-1.0.7/doc/tutorial.rst
--- old/pytest_httpserver-1.0.6/doc/tutorial.rst        2022-07-13 
18:49:54.027996000 +0200
+++ new/pytest_httpserver-1.0.7/doc/tutorial.rst        2023-05-16 
20:58:37.763110000 +0200
@@ -69,7 +69,7 @@
 It is advised to use the ``url_for()`` method to construct an URL as it will
 always contain the correct port number in the URL.
 
-If you need the http port as an integer, you can get is by the ``port``
+If you need the http port as an integer, you can get it by the ``port``
 attribute of the ``httpserver`` object.
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/pyproject.toml 
new/pytest_httpserver-1.0.7/pyproject.toml
--- old/pytest_httpserver-1.0.6/pyproject.toml  2022-09-12 09:25:14.313314400 
+0200
+++ new/pytest_httpserver-1.0.7/pyproject.toml  2023-05-16 21:40:52.284019700 
+0200
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "pytest_httpserver"
-version = "1.0.6"
+version = "1.0.7"
 description = "pytest-httpserver is a httpserver for pytest"
 authors = ["Zsolt Cserna <cserna.zs...@gmail.com>"]
 license = "MIT"
@@ -24,7 +24,7 @@
 ]
 
 [tool.poetry.dependencies]
-python = ">=3.7,<4.0"
+python = ">=3.8,<4.0"
 Werkzeug = ">= 2.0.0"
 
 
@@ -46,10 +46,11 @@
 mypy = "^0.971"
 types-requests = "^2.28.9"
 pytest = "^7.1.3"
-pytest-cov = "^3.0.0"
-coverage = "^6.4.4"
-ipdb = "^0.13.9"
+pytest-cov = ">=3,<5"
+coverage = ">=6.4.4,<8.0.0"
 types-toml = "^0.10.8"
+toml = "^0.10.2"
+black = "^23.1.0"
 
 
 [tool.poetry.group.doc]
@@ -65,13 +66,14 @@
 
 [tool.poetry.group.test.dependencies]
 pytest = "^7.1.3"
-pytest-cov = "^3.0.0"
-coverage = "^6.4.4"
+pytest-cov = ">=3,<5"
+coverage = ">=6.4.4,<8.0.0"
 requests = "^2.28.1"
 mypy = "^0.971"
 types-requests = "^2.28.9"
 pre-commit = "^2.20.0"
 types-toml = "^0.10.8"
+toml = "^0.10.2"
 
 [build-system]
 requires = ["poetry-core>=1.0.0"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/pytest_httpserver/httpserver.py 
new/pytest_httpserver-1.0.7/pytest_httpserver/httpserver.py
--- old/pytest_httpserver-1.0.6/pytest_httpserver/httpserver.py 2022-09-07 
21:46:29.731832500 +0200
+++ new/pytest_httpserver-1.0.7/pytest_httpserver/httpserver.py 2023-05-16 
20:58:37.764109800 +0200
@@ -1,9 +1,11 @@
 import abc
+import ipaddress
 import json
 import queue
 import re
 import threading
 import time
+import urllib.parse
 from collections import defaultdict
 from contextlib import contextmanager
 from contextlib import suppress
@@ -21,9 +23,9 @@
 from typing import Tuple
 from typing import Union
 
-import werkzeug.urls
+import werkzeug.http
+from werkzeug.datastructures import Authorization
 from werkzeug.datastructures import MultiDict
-from werkzeug.http import parse_authorization_header
 from werkzeug.serving import make_server
 from werkzeug.wrappers import Request
 from werkzeug.wrappers import Response
@@ -32,10 +34,12 @@
 METHOD_ALL = "__ALL"
 
 HEADERS_T = Union[
-    Mapping[str, Union[str, int, Iterable[Union[str, int]]]],
-    Iterable[Tuple[str, Union[str, int]]],
+    Mapping[str, Union[str, Iterable[str]]],
+    Iterable[Tuple[str, str]],
 ]
 
+HVMATCHER_T = Callable[[str, Optional[str], str], bool]
+
 
 class Undefined:
     def __repr__(self):
@@ -130,7 +134,10 @@
 
     @staticmethod
     def authorization_header_value_matcher(actual: Optional[str], expected: 
str) -> bool:
-        return parse_authorization_header(actual) == 
parse_authorization_header(expected)
+        callable = getattr(Authorization, "from_header", None)
+        if callable is None:  # Werkzeug < 2.3.0
+            callable = werkzeug.http.parse_authorization_header
+        return callable(actual) == callable(expected)
 
     @staticmethod
     def default_header_value_matcher(actual: Optional[str], expected: str) -> 
bool:
@@ -213,7 +220,7 @@
         self.query_dict = query_dict
 
     def get_comparing_values(self, request_query_string: bytes) -> tuple:
-        query = werkzeug.urls.url_decode(request_query_string)
+        query = 
MultiDict(urllib.parse.parse_qsl(request_query_string.decode("utf-8")))
         if isinstance(self.query_dict, MultiDict):
             return (query, self.query_dict)
         else:
@@ -288,6 +295,13 @@
         specified in the request. If multiple values specified for a given 
key, the first
         value will be used. If multiple values needed to be handled, use 
``MultiDict``
         object from werkzeug.
+    :param header_value_matcher: :py:class:`HeaderValueMatcher` that matches
+        values of headers, or a ``Callable[[str, Optional[str], str], bool]``
+        receiving the header key (from `headers`), header value (or `None`) 
and the expected
+        value (from `headers`) and should return ``True`` if the header 
matches, ``False`` otherwise.
+    :param json: a python object (eg. a dict) whose value will be compared to 
the request body after it
+        is loaded as json. If load fails, this matcher will be failed also. 
*Content-Type* is not checked.
+        If that's desired, add it to the headers parameter.
     """
 
     def __init__(
@@ -298,10 +312,9 @@
         data_encoding: str = "utf-8",
         headers: Optional[Mapping[str, str]] = None,
         query_string: Union[None, QueryMatcher, str, bytes, Mapping] = None,
-        header_value_matcher: Optional[HeaderValueMatcher] = None,
+        header_value_matcher: Optional[HVMATCHER_T] = None,
         json: Any = UNDEFINED,
     ):
-
         if json is not UNDEFINED and data is not None:
             raise ValueError("data and json parameters are mutually exclusive")
 
@@ -321,7 +334,10 @@
         self.data = data
         self.data_encoding = data_encoding
 
-        self.header_value_matcher = HeaderValueMatcher() if 
header_value_matcher is None else header_value_matcher
+        self.header_value_matcher: HVMATCHER_T = HeaderValueMatcher()
+
+        if header_value_matcher is not None:
+            self.header_value_matcher = header_value_matcher
 
     def __repr__(self):
         """
@@ -610,6 +626,9 @@
         self.ssl_context = ssl_context
         self.no_handler_status_code = 500
 
+    def __repr__(self):
+        return f"<{self.__class__.__name__} host={self.host} port={self.port}>"
+
     def clear(self):
         """
         Clears and resets the state attributes of the object.
@@ -650,6 +669,11 @@
         This basically means that it prepends the string 
``http://$HOST:$PORT/`` to the `suffix` parameter
         (where $HOST and $PORT are the parameters given to the constructor).
 
+        When host is an IPv6 address, the required square brackets will be 
added
+        to it, forming a valid URL.
+
+        When SSL or TLS is in use, the protocol of the returned URL will be 
``https``.
+
         :param suffix: the suffix which will be added to the base url. It can 
start with ``/`` (slash) or
             not, the url will be the same.
         :return: the full url which refers to the server
@@ -663,7 +687,9 @@
         else:
             protocol = "https"
 
-        return "{}://{}:{}{}".format(protocol, self.host, self.port, suffix)
+        host = self.format_host(self.host)
+
+        return "{}://{}:{}{}".format(protocol, host, self.port, suffix)
 
     def create_matcher(self, *args, **kwargs) -> RequestMatcher:
         """
@@ -837,6 +863,24 @@
         if self.is_running():
             self.stop()
 
+    @staticmethod
+    def format_host(host):
+        """
+        Formats a hostname so it can be used in a URL.
+        Notably, this adds brackets around IPV6 addresses when
+        they are missing.
+        """
+        try:
+            ipaddress.IPv6Address(host)
+            is_ipv6 = True
+        except ValueError:
+            is_ipv6 = False
+
+        if is_ipv6 and not host.startswith("[") and not host.endswith("]"):
+            return f"[{host}]"
+
+        return host
+
 
 class HTTPServer(HTTPServerBase):  # pylint: 
disable=too-many-instance-attributes
     """
@@ -910,7 +954,7 @@
         data_encoding: str = "utf-8",
         headers: Optional[Mapping[str, str]] = None,
         query_string: Union[None, QueryMatcher, str, bytes, Mapping] = None,
-        header_value_matcher: Optional[HeaderValueMatcher] = None,
+        header_value_matcher: Optional[HVMATCHER_T] = None,
         handler_type: HandlerType = HandlerType.PERMANENT,
         json: Any = UNDEFINED,
     ) -> RequestHandler:
@@ -944,7 +988,10 @@
             specified in the request. If multiple values specified for a given 
key, the first
             value will be used. If multiple values needed to be handled, use 
``MultiDict``
             object from werkzeug.
-        :param header_value_matcher: :py:class:`HeaderValueMatcher` that 
matches values of headers.
+        :param header_value_matcher: :py:class:`HeaderValueMatcher` that 
matches
+            values of headers, or a ``Callable[[str, Optional[str], str], 
bool]``
+            receiving the header key (from `headers`), header value (or 
`None`) and the expected
+            value (from `headers`) and should return ``True`` if the header 
matches, ``False`` otherwise.
         :param handler_type: type of handler
         :param json: a python object (eg. a dict) whose value will be compared 
to the request body after it
             is loaded as json. If load fails, this matcher will be failed 
also. *Content-Type* is not checked.
@@ -982,7 +1029,7 @@
         data_encoding: str = "utf-8",
         headers: Optional[Mapping[str, str]] = None,
         query_string: Union[None, QueryMatcher, str, bytes, Mapping] = None,
-        header_value_matcher: Optional[HeaderValueMatcher] = None,
+        header_value_matcher: Optional[HVMATCHER_T] = None,
         json: Any = UNDEFINED,
     ) -> RequestHandler:
         """
@@ -1004,7 +1051,10 @@
             specified in the request. If multiple values specified for a given 
key, the first
             value will be used. If multiple values needed to be handled, use 
``MultiDict``
             object from werkzeug.
-        :param header_value_matcher: :py:class:`HeaderValueMatcher` that 
matches values of headers.
+        :param header_value_matcher: :py:class:`HeaderValueMatcher` that 
matches
+            values of headers, or a ``Callable[[str, Optional[str], str], 
bool]``
+            receiving the header key (from `headers`), header value (or 
`None`) and the expected
+            value (from `headers`) and should return ``True`` if the header 
matches, ``False`` otherwise.
         :param json: a python object (eg. a dict) whose value will be compared 
to the request body after it
             is loaded as json. If load fails, this matcher will be failed 
also. *Content-Type* is not checked.
             If that's desired, add it to the headers parameter.
@@ -1034,7 +1084,7 @@
         data_encoding: str = "utf-8",
         headers: Optional[Mapping[str, str]] = None,
         query_string: Union[None, QueryMatcher, str, bytes, Mapping] = None,
-        header_value_matcher: Optional[HeaderValueMatcher] = None,
+        header_value_matcher: Optional[HVMATCHER_T] = None,
         json: Any = UNDEFINED,
     ) -> RequestHandler:
         """
@@ -1056,7 +1106,10 @@
             specified in the request. If multiple values specified for a given 
key, the first
             value will be used. If multiple values needed to be handled, use 
``MultiDict``
             object from werkzeug.
-        :param header_value_matcher: :py:class:`HeaderValueMatcher` that 
matches values of headers.
+        :param header_value_matcher: :py:class:`HeaderValueMatcher` that 
matches
+            values of headers, or a ``Callable[[str, Optional[str], str], 
bool]``
+            receiving the header key (from `headers`), header value (or 
`None`) and the expected
+            value (from `headers`) and should return ``True`` if the header 
matches, ``False`` otherwise.
         :param json: a python object (eg. a dict) whose value will be compared 
to the request body after it
             is loaded as json. If load fails, this matcher will be failed 
also. *Content-Type* is not checked.
             If that's desired, add it to the headers parameter.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/pytest_httpserver/pytest_plugin.py 
new/pytest_httpserver-1.0.7/pytest_httpserver/pytest_plugin.py
--- old/pytest_httpserver-1.0.6/pytest_httpserver/pytest_plugin.py      
2022-07-13 18:49:54.028996000 +0200
+++ new/pytest_httpserver-1.0.7/pytest_httpserver/pytest_plugin.py      
2023-05-16 20:58:37.764109800 +0200
@@ -66,3 +66,37 @@
     server = make_httpserver
     yield server
     server.clear()
+
+
+@pytest.fixture(scope="session")
+def make_httpserver_ipv4(httpserver_ssl_context):
+    server = HTTPServer(host="127.0.0.1", port=0, 
ssl_context=httpserver_ssl_context)
+    server.start()
+    yield server
+    server.clear()
+    if server.is_running():
+        server.stop()
+
+
+@pytest.fixture
+def httpserver_ipv4(make_httpserver_ipv4):
+    server = make_httpserver_ipv4
+    yield server
+    server.clear()
+
+
+@pytest.fixture(scope="session")
+def make_httpserver_ipv6(httpserver_ssl_context):
+    server = HTTPServer(host="::1", port=0, ssl_context=httpserver_ssl_context)
+    server.start()
+    yield server
+    server.clear()
+    if server.is_running():
+        server.stop()
+
+
+@pytest.fixture
+def httpserver_ipv6(make_httpserver_ipv6):
+    server = make_httpserver_ipv6
+    yield server
+    server.clear()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/setup.py 
new/pytest_httpserver-1.0.7/setup.py
--- old/pytest_httpserver-1.0.6/setup.py        1970-01-01 01:00:00.000000000 
+0100
+++ new/pytest_httpserver-1.0.7/setup.py        1970-01-01 01:00:00.000000000 
+0100
@@ -15,7 +15,7 @@
 
 setup_kwargs = {
     'name': 'pytest-httpserver',
-    'version': '1.0.6',
+    'version': '1.0.7',
     'description': 'pytest-httpserver is a httpserver for pytest',
     'long_description': '[![Build 
Status](https://github.com/csernazs/pytest-httpserver/workflows/build/badge.svg?branch=master)](https://github.com/csernazs/pytest-httpserver/actions?query=workflow%3Abuild+branch%3Amaster)\n[![Documentation
 
Status](https://readthedocs.org/projects/pytest-httpserver/badge/?version=latest)](https://pytest-httpserver.readthedocs.io/en/latest/?badge=latest)\n
 [![License: 
MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=K6PU3AGBZW4QC&item_name=pytest-httpserver&currency_code=EUR&source=url)\n[![codecov](https://codecov.io/gh/csernazs/pytest-httpserver/branch/master/graph/badge.svg?token=MX2JXbHqRH)](https://codecov.io/gh/csernazs/pytest-httpserver)\n[![Code
 style: 
black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n##
 pytest_httpserve
 r\n\nHTTP server for pytest\n\n\n### Nutshell\n\nThis library is designed to 
help to test http clients without contacting the real http server.\nIn other 
words, it is a fake http server which is accessible via localhost can be 
started with\nthe pre-defined expected http requests and their 
responses.\n\n### Example\n\n#### Handling a simple GET request\n```python\ndef 
test_my_client(\n    httpserver,\n):  # httpserver is a pytest fixture which 
starts the server\n    # set up the server to serve /foobar with the json\n    
httpserver.expect_request("/foobar").respond_with_json({"foo": "bar"})\n    # 
check that the request is served\n    assert 
requests.get(httpserver.url_for("/foobar")).json() == {"foo": 
"bar"}\n```\n\n#### Handing a POST request with an expected json 
body\n```python\ndef test_json_request(\n    httpserver,\n):  # httpserver is a 
pytest fixture which starts the server\n    # set up the server to serve 
/foobar with the json\n    httpserver.expect_request(\n        "/foo
 bar", method="POST", json={"id": 12, "name": "foo"}\n    
).respond_with_json({"foo": "bar"})\n    # check that the request is served\n   
 assert requests.post(\n        httpserver.url_for("/foobar"), json={"id": 12, 
"name": "foo"}\n    ).json() == {"foo": "bar"}\n```\n\n\nYou can also use the 
library without pytest. There\'s a with statement to ensure that the server is 
stopped.\n\n\n```python\nwith HTTPServer() as httpserver:\n    # set up the 
server to serve /foobar with the json\n    
httpserver.expect_request("/foobar").respond_with_json({"foo": "bar"})\n    # 
check that the request is served\n    
print(requests.get(httpserver.url_for("/foobar")).json())\n```\n\n### 
Documentation\n\nPlease find the API documentation at 
https://pytest-httpserver.readthedocs.io/en/latest/.\n\n### Features\n\nYou can 
set up a dozen of expectations for the requests, and also what response should 
be sent by the server to the client.\n\n\n#### Requests\n\nThere are three 
different types:\n\n- **permane
 nt**: this will be always served when there\'s match for this request, you can 
make as many HTTP requests as you want\n- **oneshot**: this will be served only 
once when there\'s a match for this request, you can only make 1 HTTP 
request\n- **ordered**: same as oneshot but the order must be strictly matched 
to the order of setting up\n\nYou can also fine-tune the expected request. The 
following can be specified:\n\n- URI (this is a must)\n- HTTP method\n- 
headers\n- query string\n- data (HTTP body of the request)\n- JSON (HTTP body 
loaded as JSON)\n\n\n#### Responses\n\nOnce you have the expectations for the 
request set up, you should also define the response you want to send back.\nThe 
following is supported currently:\n\n- respond arbitrary data (string or 
bytearray)\n- respond a json (a python dict converted in-place to json)\n- 
respond a Response object of werkzeug\n- use your own function\n\nSimilar to 
requests, you can fine-tune what response you want to send:\n\n- HTTP status\
 n- headers\n- data\n\n\n#### Behave support\n\nUsing the `BlockingHTTPServer` 
class, the assertion for a request and the\nresponse can be performed in real 
order. For more info, see the\n[test](tests/test_blocking_httpserver.py), 
the\n[howto](https://pytest-httpserver.readthedocs.io/en/latest/howto.html#running-httpserver-in-blocking-mode)\nand
 the 
[API\ndocumentation](https://pytest-httpserver.readthedocs.io/en/latest/api.html#blockinghttpserver).\n\n\n###
 Missing features\n* HTTP/2\n* Keepalive\n* ~~TLS~~\n\n### Donation\n\nIf you 
want to donate to this project, you can find the donate button at the top\nof 
the README.\n\nCurrently, this project is based heavily on werkzeug. Werkzeug 
does all the heavy lifting\nbehind the scenes, parsing HTTP request and 
defining Request and Response objects, which\nare currently transparent in the 
API.\n\nIf you wish to donate, please consider donating to them: 
https://palletsprojects.com/donate\n',
     'author': 'Zsolt Cserna',
@@ -27,7 +27,7 @@
     'package_data': package_data,
     'install_requires': install_requires,
     'entry_points': entry_points,
-    'python_requires': '>=3.7,<4.0',
+    'python_requires': '>=3.8,<4.0',
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_example_blocking_httpserver.py 
new/pytest_httpserver-1.0.7/tests/examples/test_example_blocking_httpserver.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_example_blocking_httpserver.py  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_example_blocking_httpserver.py  
    2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,59 @@
+import threading
+from queue import Queue
+
+import pytest
+import requests
+
+from pytest_httpserver import BlockingHTTPServer
+
+# override httpserver fixture
+
+
+@pytest.fixture
+def httpserver():
+    server = BlockingHTTPServer(timeout=1)
+    server.start()
+
+    yield server
+
+    server.clear()
+    if server.is_running():
+        server.stop()
+
+    # this is to check if the client has made any request where no
+    # `assert_request` was called on it from the test
+
+    server.check_assertions()
+    server.clear()
+
+
+def test_simplified(httpserver: BlockingHTTPServer):
+    def client(response_queue: Queue):
+        response = requests.get(httpserver.url_for("/foobar"), timeout=10)
+        response_queue.put(response)
+
+    # start the client, server is not yet configured
+    # it will block until we add a request handler to the server
+    # (see the timeout parameter of the http server)
+    response_queue: Queue[requests.models.Response] = Queue(maxsize=1)
+    thread = threading.Thread(target=client, args=(response_queue,))
+    thread.start()
+
+    try:
+        # check that the request is for /foobar and it is a GET method
+        # if this does not match, it will raise AssertionError and test will 
fail
+        client_connection = httpserver.assert_request(uri="/foobar", 
method="GET")
+
+        # with the received client_connection, we now need to send back the 
response
+        # this makes the request.get() call in client() to return
+        client_connection.respond_with_json({"foo": "bar"})
+
+    finally:
+        # wait for the client thread to complete
+        thread.join(timeout=1)
+        assert not thread.is_alive()  # check if join() has not timed out
+
+    # check the response the client received
+    response = response_queue.get(timeout=1)
+    assert response.status_code == 200
+    assert response.json() == {"foo": "bar"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_example_query_params1.py 
new/pytest_httpserver-1.0.7/tests/examples/test_example_query_params1.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_example_query_params1.py    
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_example_query_params1.py    
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,2 @@
+def test_query_params(httpserver):
+    httpserver.expect_request("/foo", query_string={"user": 
"user1"}).respond_with_data("OK")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_example_query_params2.py 
new/pytest_httpserver-1.0.7/tests/examples/test_example_query_params2.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_example_query_params2.py    
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_example_query_params2.py    
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,3 @@
+def test_query_params(httpserver):
+    expected_query = {"user": "user1"}
+    httpserver.expect_request("/foo", 
query_string=expected_query).respond_with_data("OK")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_authorization_headers.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_authorization_headers.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_authorization_headers.py  
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_authorization_headers.py  
    2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,40 @@
+import requests
+
+from pytest_httpserver import HTTPServer
+
+
+def test_authorization_headers(httpserver: HTTPServer):
+    headers_with_values_in_direct_order = {
+        "Authorization": (
+            'Digest username="Mufasa",'
+            'realm="testre...@host.com",'
+            'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",'
+            'uri="/dir/index.html",'
+            "qop=auth,"
+            "nc=00000001,"
+            'cnonce="0a4f113b",'
+            'response="6629fae49393a05397450978507c4ef1",'
+            'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
+        )
+    }
+    httpserver.expect_request(uri="/", 
headers=headers_with_values_in_direct_order).respond_with_data("OK")
+    response = requests.get(httpserver.url_for("/"), 
headers=headers_with_values_in_direct_order)
+    assert response.status_code == 200
+    assert response.text == "OK"
+
+    headers_with_values_in_modified_order = {
+        "Authorization": (
+            "Digest qop=auth,"
+            'username="Mufasa",'
+            'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",'
+            'uri="/dir/index.html",'
+            "nc=00000001,"
+            'realm="testre...@host.com",'
+            'response="6629fae49393a05397450978507c4ef1",'
+            'cnonce="0a4f113b",'
+            'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
+        )
+    }
+    response = requests.get(httpserver.url_for("/"), 
headers=headers_with_values_in_modified_order)
+    assert response.status_code == 200
+    assert response.text == "OK"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_case_insensitive_matcher.py
 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_case_insensitive_matcher.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_case_insensitive_matcher.py
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_case_insensitive_matcher.py
   2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,24 @@
+from typing import Optional
+
+import requests
+
+from pytest_httpserver import HTTPServer
+
+
+def case_insensitive_matcher(header_name: str, actual: Optional[str], 
expected: str) -> bool:
+    if actual is None:
+        return False
+
+    if header_name == "X-Foo":
+        return actual.lower() == expected.lower()
+    else:
+        return actual == expected
+
+
+def test_case_insensitive_matching(httpserver: HTTPServer):
+    httpserver.expect_request(
+        "/", header_value_matcher=case_insensitive_matcher, headers={"X-Foo": 
"bar"}
+    ).respond_with_data("OK")
+
+    assert requests.get(httpserver.url_for("/"), headers={"X-Foo": 
"bar"}).status_code == 200
+    assert requests.get(httpserver.url_for("/"), headers={"X-Foo": 
"BAR"}).status_code == 200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_check.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_check.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_check.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_check.py      
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,17 @@
+import pytest
+import requests
+
+from pytest_httpserver import HTTPServer
+
+
+@pytest.mark.xfail
+def test_check_assertions(httpserver: HTTPServer):
+    def handler(_):
+        assert 1 == 2
+
+    httpserver.expect_request("/foobar").respond_with_handler(handler)
+
+    requests.get(httpserver.url_for("/foobar"))
+
+    # this will raise AssertionError:
+    httpserver.check()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_check_handler_errors.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_check_handler_errors.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_check_handler_errors.py   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_check_handler_errors.py   
    2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,37 @@
+import pytest
+import requests
+
+from pytest_httpserver import HTTPServer
+
+
+def test_check_assertions_raises_handler_assertions(httpserver: HTTPServer):
+    def handler(_):
+        assert 1 == 2
+
+    httpserver.expect_request("/foobar").respond_with_handler(handler)
+
+    requests.get(httpserver.url_for("/foobar"))
+
+    # if you leave this "with" statement out, check_assertions() will break
+    # the test by re-raising the assertion error caused by the handler
+    # pytest will pick this exception as it was happened in the main thread
+    with pytest.raises(AssertionError):
+        httpserver.check_assertions()
+
+    httpserver.check_handler_errors()
+
+
+def test_check_handler_errors_raises_handler_error(httpserver: HTTPServer):
+    def handler(_):
+        raise ValueError("should be propagated")
+
+    httpserver.expect_request("/foobar").respond_with_handler(handler)
+
+    requests.get(httpserver.url_for("/foobar"))
+
+    httpserver.check_assertions()
+
+    # if you leave this "with" statement out, check_handler_errors() will
+    # break the test with the original exception
+    with pytest.raises(ValueError):
+        httpserver.check_handler_errors()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_custom_handler.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_custom_handler.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_custom_handler.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_custom_handler.py     
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,13 @@
+from random import randint
+
+from werkzeug.wrappers import Request
+from werkzeug.wrappers import Response
+
+from pytest_httpserver import HTTPServer
+
+
+def test_expected_request_handler(httpserver: HTTPServer):
+    def handler(request: Request):
+        return Response(str(randint(1, 10)))
+
+    httpserver.expect_request("/foobar").respond_with_handler(handler)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_header_value_matcher.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_header_value_matcher.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_header_value_matcher.py   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_header_value_matcher.py   
    2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,22 @@
+from typing import Optional
+
+import requests
+
+from pytest_httpserver import HeaderValueMatcher
+from pytest_httpserver import HTTPServer
+
+
+def case_insensitive_compare(actual: Optional[str], expected: str) -> bool:
+    # actual is `None` if it is not specified
+    if actual is None:
+        return False
+    return actual.lower() == expected.lower()
+
+
+def test_own_matcher_object(httpserver: HTTPServer):
+    matcher = HeaderValueMatcher({"X-Bar": case_insensitive_compare})
+
+    httpserver.expect_request("/", headers={"X-Bar": "bar"}, 
header_value_matcher=matcher).respond_with_data("OK")
+
+    assert requests.get(httpserver.url_for("/"), headers={"X-Bar": 
"bar"}).status_code == 200
+    assert requests.get(httpserver.url_for("/"), headers={"X-Bar": 
"BAR"}).status_code == 200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_json_matcher.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_json_matcher.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_json_matcher.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_json_matcher.py       
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,10 @@
+import requests
+
+from pytest_httpserver import HTTPServer
+
+
+def test_json_matcher(httpserver: HTTPServer):
+    httpserver.expect_request("/foo", json={"foo": 
"bar"}).respond_with_data("Hello world!")
+    resp = requests.get(httpserver.url_for("/foo"), json={"foo": "bar"})
+    assert resp.status_code == 200
+    assert resp.text == "Hello world!"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_query_params_dict.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_query_params_dict.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_query_params_dict.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_query_params_dict.py  
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,8 @@
+import requests
+
+
+def test_query_params(httpserver):
+    httpserver.expect_request("/foo", query_string={"user": "user1", "group": 
"group1"}).respond_with_data("OK")
+
+    assert 
requests.get(httpserver.url_for("/foo?user=user1&group=group1")).status_code == 
200
+    assert 
requests.get(httpserver.url_for("/foo?group=group1&user=user1")).status_code == 
200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_query_params_never_do_this.py
 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_query_params_never_do_this.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_query_params_never_do_this.py
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_query_params_never_do_this.py
 2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,2 @@
+def test_query_params(httpserver):
+    httpserver.expect_request("/foo?user=bar")  # never do this
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_query_params_proper_use.py
 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_query_params_proper_use.py
--- 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_query_params_proper_use.py
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_query_params_proper_use.py
    2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,2 @@
+def test_query_params(httpserver):
+    httpserver.expect_request("/foo", query_string="user=bar")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_regexp.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_regexp.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_regexp.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_regexp.py     
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,8 @@
+import re
+
+import requests
+
+
+def test_httpserver_with_regexp(httpserver):
+    httpserver.expect_request(re.compile("^/foo"), method="GET")
+    requests.get(httpserver.url_for("/foobar"))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_timeout_requests.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_timeout_requests.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_timeout_requests.py   
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_timeout_requests.py   
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,8 @@
+import pytest
+import requests
+
+
+def test_connection_refused():
+    # assumes that there's no server listening at localhost:1234
+    with pytest.raises(requests.exceptions.ConnectionError):
+        requests.get("http://localhost:1234";)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_url_matcher.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_url_matcher.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_url_matcher.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_url_matcher.py        
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,14 @@
+from pytest_httpserver import HTTPServer
+from pytest_httpserver import URIPattern
+
+
+class PrefixMatch(URIPattern):
+    def __init__(self, prefix: str):
+        self.prefix = prefix
+
+    def match(self, uri):
+        return uri.startswith(self.prefix)
+
+
+def test_uripattern_object(httpserver: HTTPServer):
+    httpserver.expect_request(PrefixMatch("/foo")).respond_with_json({"foo": 
"bar"})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/examples/test_howto_wait_success.py 
new/pytest_httpserver-1.0.7/tests/examples/test_howto_wait_success.py
--- old/pytest_httpserver-1.0.6/tests/examples/test_howto_wait_success.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/examples/test_howto_wait_success.py       
2023-05-16 20:58:37.764109800 +0200
@@ -0,0 +1,20 @@
+import requests
+
+from pytest_httpserver import HTTPServer
+
+
+def test_wait_success(httpserver: HTTPServer):
+    waiting_timeout = 0.1
+
+    with httpserver.wait(stop_on_nohandler=False, timeout=waiting_timeout) as 
waiting:
+        requests.get(httpserver.url_for("/foobar"))
+        httpserver.expect_oneshot_request("/foobar").respond_with_data("OK 
foobar")
+        requests.get(httpserver.url_for("/foobar"))
+    assert waiting.result
+
+    httpserver.expect_oneshot_request("/foobar").respond_with_data("OK foobar")
+    httpserver.expect_oneshot_request("/foobaz").respond_with_data("OK foobaz")
+    with httpserver.wait(timeout=waiting_timeout) as waiting:
+        requests.get(httpserver.url_for("/foobar"))
+        requests.get(httpserver.url_for("/foobaz"))
+    assert waiting.result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/test_blocking_httpserver.py 
new/pytest_httpserver-1.0.7/tests/test_blocking_httpserver.py
--- old/pytest_httpserver-1.0.6/tests/test_blocking_httpserver.py       
2022-09-09 09:40:14.155206700 +0200
+++ new/pytest_httpserver-1.0.7/tests/test_blocking_httpserver.py       
2023-05-16 20:58:37.765109800 +0200
@@ -59,7 +59,6 @@
     )
 
     with when_a_request_is_being_sent_to_the_server(request) as 
server_connection:
-
         client_connection = then_the_server_gets_the_request(httpserver, 
request)
 
         response = {"foo": "bar"}
@@ -76,7 +75,6 @@
     )
 
     with when_a_request_is_being_sent_to_the_server(request):
-
         with pytest.raises(AssertionError) as exc:
             httpserver.assert_request(uri="/not/my/path/")
 
@@ -99,7 +97,6 @@
     )
 
     with when_a_request_is_being_sent_to_the_server(request) as 
server_connection:
-
         assert server_connection.get(timeout=9).text == "No handler found for 
this request"
 
 
@@ -110,7 +107,6 @@
     )
 
     with when_a_request_is_being_sent_to_the_server(request):
-
         then_the_server_gets_the_request(httpserver, request)
 
         httpserver.stop()  # waiting for timeout of waiting for the response
@@ -120,3 +116,7 @@
 
         assert "/my/path" in str(exc)
         assert "no response" in str(exc).lower()
+
+
+def test_repr(httpserver: BlockingHTTPServer):
+    assert repr(httpserver) == f"<BlockingHTTPServer host=localhost 
port={httpserver.port}>"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_httpserver-1.0.6/tests/test_blocking_httpserver_howto.py 
new/pytest_httpserver-1.0.7/tests/test_blocking_httpserver_howto.py
--- old/pytest_httpserver-1.0.6/tests/test_blocking_httpserver_howto.py 
2022-09-12 08:46:31.629976300 +0200
+++ new/pytest_httpserver-1.0.7/tests/test_blocking_httpserver_howto.py 
1970-01-01 01:00:00.000000000 +0100
@@ -1,59 +0,0 @@
-import threading
-from queue import Queue
-
-import pytest
-import requests
-
-from pytest_httpserver import BlockingHTTPServer
-
-# override httpserver fixture
-
-
-@pytest.fixture
-def httpserver():
-    server = BlockingHTTPServer(timeout=1)
-    server.start()
-
-    yield server
-
-    server.clear()
-    if server.is_running():
-        server.stop()
-
-    # this is to check if the client has made any request where no
-    # `assert_request` was called on it from the test
-
-    server.check_assertions()
-    server.clear()
-
-
-def test_simplified(httpserver: BlockingHTTPServer):
-    def client(response_queue: Queue):
-        response = requests.get(httpserver.url_for("/foobar"), timeout=10)
-        response_queue.put(response)
-
-    # start the client, server is not yet configured
-    # it will block until we add a request handler to the server
-    # (see the timeout parameter of the http server)
-    response_queue: Queue[requests.models.Response] = Queue(maxsize=1)
-    thread = threading.Thread(target=client, args=(response_queue,))
-    thread.start()
-
-    try:
-        # check that the request is for /foobar and it is a GET method
-        # if this does not match, it will raise AssertionError and test will 
fail
-        client_connection = httpserver.assert_request(uri="/foobar", 
method="GET")
-
-        # with the received client_connection, we now need to send back the 
response
-        # this makes the request.get() call in client() to return
-        client_connection.respond_with_json({"foo": "bar"})
-
-    finally:
-        # wait for the client thread to complete
-        thread.join(timeout=1)
-        assert not thread.is_alive()  # check if join() has not timed out
-
-    # check the response the client received
-    response = response_queue.get(timeout=1)
-    assert response.status_code == 200
-    assert response.json() == {"foo": "bar"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/tests/test_headers.py 
new/pytest_httpserver-1.0.7/tests/test_headers.py
--- old/pytest_httpserver-1.0.6/tests/test_headers.py   2022-07-13 
18:49:54.028996000 +0200
+++ new/pytest_httpserver-1.0.7/tests/test_headers.py   2023-05-16 
20:58:37.765109800 +0200
@@ -82,15 +82,14 @@
 def test_header_one_key_multiple_values(httpserver: HTTPServer):
     httpserver.expect_request(uri="/t1").respond_with_data(headers=[("X-Foo", 
"123"), ("X-Foo", "456")])
     httpserver.expect_request(uri="/t2").respond_with_data(headers={"X-Foo": 
["123", "456"]})
-    httpserver.expect_request(uri="/t3").respond_with_data(headers={"X-Foo": 
[123, 456]})
 
     headers = Headers()
     headers.add("X-Foo", "123")
     headers.add("X-Foo", "456")
 
-    httpserver.expect_request(uri="/t4").respond_with_data(headers=headers)
+    httpserver.expect_request(uri="/t3").respond_with_data(headers=headers)
 
-    for uri in ("/t1", "/t2", "/t3", "/t4"):
+    for uri in ("/t1", "/t2", "/t3"):
         conn = 
http.client.HTTPConnection("localhost:{}".format(httpserver.port))
         conn.request("GET", uri)
         response = conn.getresponse()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/tests/test_ip_protocols.py 
new/pytest_httpserver-1.0.7/tests/test_ip_protocols.py
--- old/pytest_httpserver-1.0.6/tests/test_ip_protocols.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/test_ip_protocols.py      2023-05-16 
20:58:37.765109800 +0200
@@ -0,0 +1,18 @@
+import requests
+
+
+def test_ipv4(httpserver_ipv4):
+    httpserver_ipv4.expect_request("/").respond_with_data("OK")
+    assert httpserver_ipv4.host == "127.0.0.1"
+
+    response = requests.get(httpserver_ipv4.url_for("/"))
+    assert response.text == "OK"
+
+
+def test_ipv6(httpserver_ipv6):
+    httpserver_ipv6.expect_request("/").respond_with_data("OK")
+    assert httpserver_ipv6.host == "::1"
+    assert httpserver_ipv6.url_for("/") == 
f"http://[::1]:{httpserver_ipv6.port}/";
+
+    response = requests.get(httpserver_ipv6.url_for("/"))
+    assert response.text == "OK"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/tests/test_mixed.py 
new/pytest_httpserver-1.0.7/tests/test_mixed.py
--- old/pytest_httpserver-1.0.6/tests/test_mixed.py     2022-07-13 
18:49:54.029996000 +0200
+++ new/pytest_httpserver-1.0.7/tests/test_mixed.py     2023-05-16 
20:58:37.765109800 +0200
@@ -82,3 +82,7 @@
     assert len(httpserver.ordered_handlers) == 2
     assert len(httpserver.oneshot_handlers) == 2
     assert len(httpserver.handlers) == 1
+
+
+def test_repr(httpserver: HTTPServer):
+    assert repr(httpserver) == f"<HTTPServer host=localhost 
port={httpserver.port}>"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/tests/test_parse_qs.py 
new/pytest_httpserver-1.0.7/tests/test_parse_qs.py
--- old/pytest_httpserver-1.0.6/tests/test_parse_qs.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/pytest_httpserver-1.0.7/tests/test_parse_qs.py  2023-05-16 
20:58:37.765109800 +0200
@@ -0,0 +1,30 @@
+import urllib.parse
+from typing import List
+from typing import Tuple
+
+import pytest
+import werkzeug.urls
+from werkzeug.datastructures import MultiDict
+
+parse_qsl_semicolon_cases = [
+    ("&", []),
+    ("&&", []),
+    ("&a=b", [("a", "b")]),
+    ("a=a+b&b=b+c", [("a", "a b"), ("b", "b c")]),
+    ("a=1&a=2", [("a", "1"), ("a", "2")]),
+    ("a=", [("a", "")]),
+    ("a=foo bar&b=bar foo", [("a", "foo bar"), ("b", "bar foo")]),
+    ("a=foo%20bar&b=bar%20foo", [("a", "foo bar"), ("b", "bar foo")]),
+    ("a=%20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D", 
[("a", " !\"#$%&'()*+,/:;=?@[]")]),
+]
+
+
+@pytest.mark.parametrize("qs,expected", parse_qsl_semicolon_cases)
+def test_qsl(qs: str, expected: List[Tuple[bytes, bytes]]):
+    assert urllib.parse.parse_qsl(qs, keep_blank_values=True) == expected
+
+
+@pytest.mark.skip(reason="skipped to avoid werkzeug warnings")
+@pytest.mark.parametrize("qs,expected", parse_qsl_semicolon_cases)
+def test_qsl_werkzeug(qs: str, expected: List[Tuple[bytes, bytes]]):
+    assert werkzeug.urls.url_decode(qs) == MultiDict(expected)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/tests/test_permanent.py 
new/pytest_httpserver-1.0.7/tests/test_permanent.py
--- old/pytest_httpserver-1.0.6/tests/test_permanent.py 2022-07-13 
18:49:54.029996000 +0200
+++ new/pytest_httpserver-1.0.7/tests/test_permanent.py 2023-05-16 
20:58:37.765109800 +0200
@@ -93,3 +93,16 @@
     assert httpserver.ordered_handlers == []
     assert httpserver.oneshot_handlers == []
     assert httpserver.handlers == []
+
+
+def test_response_handler_replaced(httpserver: HTTPServer):
+    # https://github.com/csernazs/pytest-httpserver/issues/229
+    handler = httpserver.expect_request("/foobar")
+    handler.respond_with_data("FOO")
+    response = requests.get(httpserver.url_for("/foobar"))
+    assert response.text == "FOO"
+    assert response.status_code == 200
+    handler.respond_with_json({"foo": "bar"})
+    response = requests.get(httpserver.url_for("/foobar"))
+    assert response.json() == {"foo": "bar"}
+    assert response.status_code == 200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_httpserver-1.0.6/tests/test_release.py 
new/pytest_httpserver-1.0.7/tests/test_release.py
--- old/pytest_httpserver-1.0.6/tests/test_release.py   2022-09-12 
08:46:48.840120300 +0200
+++ new/pytest_httpserver-1.0.7/tests/test_release.py   2023-05-16 
20:58:37.765109800 +0200
@@ -78,7 +78,7 @@
 
 
 @pytest.fixture(scope="session")
-def build(request) -> Iterable[Build]:
+def build() -> Iterable[Build]:
     dist_path = Path("dist").resolve()
     if dist_path.is_dir():
         shutil.rmtree(dist_path)
@@ -195,15 +195,17 @@
         "tests": {
             "assets",
             "conftest.py",
+            "examples",
             "test_blocking_httpserver.py",
-            "test_blocking_httpserver_howto.py",
             "test_handler_errors.py",
             "test_headers.py",
+            "test_ip_protocols.py",
             "test_json_matcher.py",
             "test_mixed.py",
             "test_oneshot.py",
             "test_ordered.py",
             "test_permanent.py",
+            "test_parse_qs.py",
             "test_port_changing.py",
             "test_querymatcher.py",
             "test_querystring.py",

Reply via email to