diff -Nru python-jsonschema-3.2.0/.appveyor.yml python-jsonschema-4.6.0/.appveyor.yml --- python-jsonschema-3.2.0/.appveyor.yml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/.appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -build: false -environment: - VENV: "%APPVEYOR_BUILD_FOLDER%\\venv" - - matrix: - - TOXENV: py35-tests - PYTHON: "C:\\Python35" - - - TOXENV: py35-tests - PYTHON: "C:\\Python35-x64" - - - TOXENV: py36-tests - PYTHON: "C:\\Python36" - - - TOXENV: py36-tests - PYTHON: "C:\\Python36-x64" - - - TOXENV: py37-tests - PYTHON: "C:\\Python37" - - - TOXENV: py37-tests - PYTHON: "C:\\Python37-x64" - -init: - - echo "TOXENV - %TOXENV%" - -install: - - ps: Update-AppveyorBuild -Version "v$(python setup.py --version) b$Env:APPVEYOR_BUILD_NUMBER" - - virtualenv -p "%PYTHON%\\python.exe" "%VENV%" - - "%VENV%\\Scripts\\pip install tox" - -test_script: - - "%VENV%\\Scripts\\tox" diff -Nru python-jsonschema-3.2.0/CHANGELOG.rst python-jsonschema-4.6.0/CHANGELOG.rst --- python-jsonschema-3.2.0/CHANGELOG.rst 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/CHANGELOG.rst 2022-06-01 20:26:26.000000000 +0000 @@ -1,3 +1,122 @@ +v4.6.0 +------ + +* Fix ``unevaluatedProperties`` and ``unevaluatedItems`` for types they should + ignore (#949) +* ``jsonschema`` now uses `hatch `_ for its build + process. This should be completely transparent to end-users (and only matters + to contributors). + +v4.5.1 +------ + +* Revert changes to ``$dynamicRef`` which caused a performance regression + in v4.5.0 + +v4.5.0 +------ + +* Validator classes for each version now maintain references to the correct + corresponding format checker (#905) +* Development has moved to a `GitHub organization + `_. + No functional behavior changes are expected from the change. + +v4.4.0 +------ + +* Add ``mypy`` support (#892) +* Add support for Python 3.11 + +v4.3.3 +------ + +* Properly report deprecation warnings at the right stack level (#899) + +v4.3.2 +------ + +* Additional performance improvements for resolving refs (#896) + +v4.3.1 +------ + +* Resolving refs has had performance improvements (#893) + +v4.3.0 +------ + +* Fix undesired fallback to brute force container uniqueness check on + certain input types (#893) +* Implement a PEP544 Protocol for validator classes (#890) + +v4.2.1 +------ + +* Pin ``importlib.resources`` from below (#877) + +v4.2.0 +------ + +* Use ``importlib.resources`` to load schemas (#873) +* Ensure all elements of arrays are verified for uniqueness by ``uniqueItems`` + (#866) + +v4.1.2 +------ + +* Fix ``dependentSchemas`` to properly consider non-object instances to be + valid (#850) + +v4.1.1 +------ + +* Fix ``prefixItems`` not indicating which item was invalid within the instance + path (#862) + +v4.1.0 +------ + +* Add Python 3.10 to the list of supported Python versions + +v4.0.1 +------ + +* Fix the declaration of minimum supported Python version (#846) + +v4.0.0 +------ + +* Partial support for Draft 2020-12 (as well as 2019-09). + Thanks to Thomas Schmidt and Harald Nezbeda. +* ``False`` and ``0`` are now properly considered non-equal even + recursively within a container (#686). As part of this change, + ``uniqueItems`` validation may be *slower* in some cases. Please feel + free to report any significant performance regressions, though in + some cases they may be difficult to address given the specification + requirement. +* The CLI has been improved, and in particular now supports a ``--output`` + option (with ``plain`` (default) or ``pretty`` arguments) to control the + output format. Future work may add additional machine-parsable output + formats. +* Code surrounding ``DEFAULT_TYPES`` and the legacy mechanism for + specifying types to validators have been removed, as per the deprecation + policy. Validators should use the ``TypeChecker`` object to customize + the set of Python types corresponding to JSON Schema types. +* Validation errors now have a ``json_path`` attribute, describing their + location in JSON path format +* Support for the IP address and domain name formats has been improved +* Support for Python 2 and 3.6 has been dropped, with ``python_requires`` + properly set. +* ``multipleOf`` could overflow when given sufficiently large numbers. Now, + when an overflow occurs, ``jsonschema`` will fall back to using fraction + division (#746). +* ``jsonschema.__version__``, ``jsonschema.validators.validators``, + ``jsonschema.validators.meta_schemas`` and + ``jsonschema.RefResolver.in_scope`` have been deprecated, as has + passing a second-argument schema to ``Validator.iter_errors`` and + ``Validator.is_valid``. + v3.2.0 ------ @@ -43,7 +162,7 @@ * Support for Python 2.6 has been dropped. * Improve a few error messages for ``uniqueItems`` (#224) and ``additionalProperties`` (#317) -* Fixed an issue with ``ErrorTree``'s handling of multiple errors (#288) +* Fixed an issue with ``ErrorTree``'s handling of multiple errors (#288) v2.5.0 ------ @@ -175,7 +294,7 @@ In order to make this happen (and also to clean things up a bit), a number of deprecations are necessary: - * ``stop_on_error`` is deprecated in ``Validator.__init__``. Use + * ``stop_on_error`` is deprecated in ``Validator.__init__``. Use ``Validator.iter_errors()`` instead. * ``number_types`` and ``string_types`` are deprecated there as well. Use ``types={"number" : ..., "string" : ...}`` instead. diff -Nru python-jsonschema-3.2.0/codecov.yml python-jsonschema-4.6.0/codecov.yml --- python-jsonschema-3.2.0/codecov.yml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/codecov.yml 2022-06-01 20:26:26.000000000 +0000 @@ -1,11 +1,5 @@ coverage: - precision: 2 - round: down status: patch: default: target: 100% - -comment: - layout: "header, diff, uncovered" - behavior: default diff -Nru python-jsonschema-3.2.0/CONTRIBUTING.rst python-jsonschema-4.6.0/CONTRIBUTING.rst --- python-jsonschema-3.2.0/CONTRIBUTING.rst 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/CONTRIBUTING.rst 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,60 @@ +============================ +Contributing to `jsonschema` +============================ + +Found a bug? +------------ + +If you suspect you may have found a security-related vulnerability, please follow the instructions in `the security policy `_. + +Otherwise, it is extremely helpful if you first search to see whether your bug has been `previously reported on the Issues tab `_. + +If it doesn't appear to be a known issue, please `file a new one `_, and include a **title and clear description**, along with as much relevant information as possible. +Including a *minimal*, *self-sufficient* bit of code (often an instance and schema) is the fastest way to get attention, along with a description of the behavior you expect, and if you're able, a link to where in the specification contains the behavior you're noticing is incorrect. + +Pull requests to fix your issue are of course very welcome. + + +Fixing a Bug? +------------- + +Please open a new GitHub pull request with the change, along with new tests. + +Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. + +Continuous integration via GitHub actions should run to indicate whether your change passes both the test suite as well as linters. +Please ensure it passes, or indicate in a comment if you believe it fails spuriously. + + +Adding New Functionality? +------------------------- + +Please discuss any larger changes ahead of time for the sake of your own time! + +Improvements are very welcome, but large pull requests, disruptive ones, or backwards incompatible ones, can lead to long back and forth discussions. + +You're welcome to suggest a change in an issue and thereby get some initial feedback before embarking on an effort that may not get merged. + + +Improving the Documentation? +---------------------------- + +Writing good documentation is challenging both to prioritize and to do well. + +Any help you may have would be great, especially if you're a beginner who's struggled to understand a part of the library. + +Documentation is written in `Sphinx-flavored reStructuredText `_, so you'll want to familiarize yourself a bit with Sphinx. + +Feel free to file issues or pull requests. + + +Have a Question? +---------------- + +Please do not use the issue tracker for questions, it's reserved for things believed to be bugs, or new functionality. + +There is a `discussions tab `_ where general questions can be asked. + +Answers on it are best-effort. + +Any help you can offer to answer others' questions is of course very welcome as well. diff -Nru python-jsonschema-3.2.0/.coveragerc python-jsonschema-4.6.0/.coveragerc --- python-jsonschema-3.2.0/.coveragerc 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/.coveragerc 2022-06-01 20:26:26.000000000 +0000 @@ -2,4 +2,8 @@ [run] branch = True source = jsonschema -omit = */jsonschema/_reflect.py,*/jsonschema/__main__.py,*/jsonschema/benchmarks/* +omit = */jsonschema/_reflect.py,*/jsonschema/__main__.py,*/jsonschema/benchmarks/*,*/jsonschema/tests/fuzz_validate.py + +[report] +exclude_lines = + if TYPE_CHECKING: diff -Nru python-jsonschema-3.2.0/debian/changelog python-jsonschema-4.6.0/debian/changelog --- python-jsonschema-3.2.0/debian/changelog 2020-01-23 18:44:38.000000000 +0000 +++ python-jsonschema-4.6.0/debian/changelog 2022-08-02 21:06:42.000000000 +0000 @@ -1,21 +1,73 @@ -python-jsonschema (3.2.0-0ubuntu2) focal; urgency=medium +python-jsonschema (4.6.0-3ubuntu1) kinetic; urgency=medium - * Explicitly depend on python3-importlib-metadata, still needed for 3.7. - * Build-depend on python3-importlib-metadata. + * d/control: Move optional Recommends to Suggests. - -- Matthias Klose Thu, 23 Jan 2020 19:44:38 +0100 + -- Corey Bryant Tue, 02 Aug 2022 17:06:42 -0400 -python-jsonschema (3.2.0-0ubuntu1) focal; urgency=medium +python-jsonschema (4.6.0-3) unstable; urgency=medium - * New upstream version, supporting 3.8. + * Added python3-pip as depends of debian/tests/control. - -- Matthias Klose Thu, 23 Jan 2020 16:42:52 +0100 + -- Thomas Goirand Sat, 16 Jul 2022 22:07:06 +0200 -python-jsonschema (3.0.2-4build1) focal; urgency=medium +python-jsonschema (4.6.0-2) experimental; urgency=medium - * No-change rebuild to generate dependencies on python2. + * Add python3-pip to build-depends to address an otherwise failing + "python3 -m pip show jsonschema" test. - -- Matthias Klose Tue, 17 Dec 2019 12:52:55 +0000 + -- Thomas Goirand Sat, 16 Jul 2022 10:12:52 +0200 + +python-jsonschema (4.6.0-1) experimental; urgency=medium + + * New upstream release (Closes: #1005757). + * Switch to pybuild and poetry, as upstream switch to shipping a + pyproject.toml instead of setup.cfg. + * Added optional dependencies as Recommends:. + * Refreshed remove-sphinxcontrib.spelling-from-doc-conf.py.patch. + * Rebased fix-lintian-privacy-breach.patch. + * Add python3-hatch-vcs and python3-hatchling as build-depends. + * Fix PYTHONPATH when building sphinx doc. + * Add do-not-use-furo-theme.patch. + + -- Thomas Goirand Mon, 13 Jun 2022 10:51:08 +0200 + +python-jsonschema (3.2.0-5) unstable; urgency=medium + + * Fixed description (Closes: #970616). + + -- Thomas Goirand Thu, 30 Dec 2021 10:22:42 +0100 + +python-jsonschema (3.2.0-4) unstable; urgency=medium + + * Do not (build-)depends on python3-importlib-metadata (Closes: #966643). + + -- Thomas Goirand Tue, 28 Dec 2021 19:16:23 +0100 + +python-jsonschema (3.2.0-3) unstable; urgency=medium + + * Uploading to unstable. + + -- Thomas Goirand Fri, 08 May 2020 11:04:26 +0200 + +python-jsonschema (3.2.0-2) experimental; urgency=medium + + * d/control: Add {build}dependency python3-importlib-metadata + + -- Michal Arbet Tue, 05 May 2020 11:43:45 +0200 + +python-jsonschema (3.2.0-1) experimental; urgency=medium + + * New upstream version + * d/copyright: Add me to copyright + * d/control: + - Add me to uploaders + - Bump standards to 4.5.0 + - Breaks: python3-json-pointer (<< 1.14) (Closes: #949723) + * d/patches: + - Remove remove-TestBuiltinFormats-hack.patch + - Add fix-lintian-privacy-breach.patch + + -- Michal Arbet Tue, 05 May 2020 09:21:24 +0200 python-jsonschema (3.0.2-4) unstable; urgency=medium diff -Nru python-jsonschema-3.2.0/debian/control python-jsonschema-4.6.0/debian/control --- python-jsonschema-3.2.0/debian/control 2020-01-23 18:44:38.000000000 +0000 +++ python-jsonschema-4.6.0/debian/control 2022-08-02 21:06:42.000000000 +0000 @@ -1,30 +1,41 @@ Source: python-jsonschema Section: python Priority: optional -Maintainer: Debian OpenStack +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian OpenStack Uploaders: Thomas Goirand , + Michal Arbet , Build-Depends: autopkgtest, - debhelper-compat (= 12), + debhelper-compat (= 13), dh-python, openstack-pkg-tools, + pybuild-plugin-pyproject, python3-all, + python3-poetry-core, python3-setuptools, python3-setuptools-scm, python3-sphinx, Build-Depends-Indep: python3-attr, - python3-importlib-metadata, + python3-hatch-vcs, + python3-hatchling, + python3-idna, + python3-json-pointer, python3-lxml, python3-mock, python3-nose, + python3-pip, python3-pkg-resources, python3-pyrsistent, python3-pytest, + python3-rfc3987, python3-six, python3-twisted, -Standards-Version: 4.4.1 + python3-uritemplate, + python3-webcolors, +Standards-Version: 4.5.0 Vcs-Git: https://salsa.debian.org/openstack-team/third-party/python-jsonschema.git Vcs-Browser: https://salsa.debian.org/openstack-team/third-party/python-jsonschema Homepage: https://github.com/Julian/jsonschema @@ -35,7 +46,7 @@ Depends: ${misc:Depends}, ${sphinxdoc:Depends}, -Description: An(other) implementation of JSON Schema (Draft 3 and 4) - doc +Description: An(other) implementation of JSON Schema (Draft 3, 4, 6, 7) - doc JSON Schema is a specification for a JSON-based format for defining the structure of JSON data. JSON Schema provides a contract for what JSON data is required for a given application and how it can be @@ -52,17 +63,21 @@ python3-pkg-resources, python3-setuptools, python3-six, - python3-importlib-metadata, ${misc:Depends}, ${python3:Depends}, Suggests: python-jsonschema-doc, -Description: An(other) implementation of JSON Schema (Draft 3 and 4) - Python 3.x + python3-idna, + python3-json-pointer, + python3-rfc3987, + python3-uritemplate, + python3-webcolors, +Breaks: + python3-json-pointer (<< 1.14), +Description: An(other) implementation of JSON Schema (Draft 3, 4, 6, 7) JSON Schema is a specification for a JSON-based format for defining the structure of JSON data. JSON Schema provides a contract for what JSON data is required for a given application and how it can be modified, much like what XML Schema provides for XML. JSON Schema is intended to provide validation, documentation, and interaction control of JSON data. - . - This package contains the Python 3.x module. diff -Nru python-jsonschema-3.2.0/debian/copyright python-jsonschema-4.6.0/debian/copyright --- python-jsonschema-3.2.0/debian/copyright 2019-12-09 10:31:53.000000000 +0000 +++ python-jsonschema-4.6.0/debian/copyright 2022-07-16 20:07:06.000000000 +0000 @@ -27,6 +27,7 @@ Copyright: 2012 Chuck Short 2012, Ghe Rivero 2013, Thomas Goirand + 2020, Michal Arbet License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -Nru python-jsonschema-3.2.0/debian/patches/do-not-use-furo-theme.patch python-jsonschema-4.6.0/debian/patches/do-not-use-furo-theme.patch --- python-jsonschema-3.2.0/debian/patches/do-not-use-furo-theme.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/debian/patches/do-not-use-furo-theme.patch 2022-07-16 20:07:06.000000000 +0000 @@ -0,0 +1,18 @@ +Description: Do not use furo theme + This Sphinx theme isn't available in Debian, and I don't think it's + important, so just disabling it for now. +Author: Thomas Goirand +Forwarded: not-needed +Last-Update: 2022-06-13 + +--- python-jsonschema-4.6.0.orig/docs/conf.py ++++ python-jsonschema-4.6.0/docs/conf.py +@@ -86,7 +86,7 @@ intersphinx_mapping = { + + # The theme to use for HTML and HTML Help pages. See the documentation for + # a list of builtin themes. +-html_theme = "furo" ++#html_theme = "furo" + + # Theme options are theme-specific and customize the look and feel of a theme + # further. For a list of options available for each theme, see the diff -Nru python-jsonschema-3.2.0/debian/patches/fix-lintian-privacy-breach.patch python-jsonschema-4.6.0/debian/patches/fix-lintian-privacy-breach.patch --- python-jsonschema-3.2.0/debian/patches/fix-lintian-privacy-breach.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/debian/patches/fix-lintian-privacy-breach.patch 2022-07-16 20:07:06.000000000 +0000 @@ -0,0 +1,42 @@ +Description: Remove external sources from doc. +Author: Michal Arbet +Forwarded: not-needed +Last-Update: 2020-05-05 + +diff --git a/README.rst b/README.rst +index ccfb55d..3f7d111 100644 +--- a/README.rst ++++ b/README.rst +@@ -2,32 +2,6 @@ + jsonschema + ========== + +-|PyPI| |Pythons| |CI| |ReadTheDocs| |Precommit| |Zenodo| +- +-.. |PyPI| image:: https://img.shields.io/pypi/v/jsonschema.svg +- :alt: PyPI version +- :target: https://pypi.org/project/jsonschema/ +- +-.. |Pythons| image:: https://img.shields.io/pypi/pyversions/jsonschema.svg +- :alt: Supported Python versions +- :target: https://pypi.org/project/jsonschema/ +- +-.. |CI| image:: https://github.com/python-jsonschema/jsonschema/workflows/CI/badge.svg +- :alt: Build status +- :target: https://github.com/python-jsonschema/jsonschema/actions?query=workflow%3ACI +- +-.. |ReadTheDocs| image:: https://readthedocs.org/projects/python-jsonschema/badge/?version=stable&style=flat +- :alt: ReadTheDocs status +- :target: https://python-jsonschema.readthedocs.io/en/stable/ +- +-.. |Precommit| image:: https://results.pre-commit.ci/badge/github/python-jsonschema/jsonschema/main.svg +- :alt: pre-commit.ci status +- :target: https://results.pre-commit.ci/latest/github/python-jsonschema/jsonschema/main +- +-.. |Zenodo| image:: https://zenodo.org/badge/3072629.svg +- :target: https://zenodo.org/badge/latestdoi/3072629 +- +- + ``jsonschema`` is an implementation of the `JSON Schema + `_ specification for Python. + diff -Nru python-jsonschema-3.2.0/debian/patches/remove-sphinxcontrib.spelling-from-doc-conf.py.patch python-jsonschema-4.6.0/debian/patches/remove-sphinxcontrib.spelling-from-doc-conf.py.patch --- python-jsonschema-3.2.0/debian/patches/remove-sphinxcontrib.spelling-from-doc-conf.py.patch 2019-12-09 10:31:53.000000000 +0000 +++ python-jsonschema-4.6.0/debian/patches/remove-sphinxcontrib.spelling-from-doc-conf.py.patch 2022-07-16 20:07:06.000000000 +0000 @@ -4,10 +4,12 @@ Forwarded: not-needed Last-Update: 2019-09-24 ---- python-jsonschema-3.0.2.orig/docs/conf.py -+++ python-jsonschema-3.0.2/docs/conf.py -@@ -26,11 +26,8 @@ - "sphinx.ext.autodoc", +Index: python-jsonschema/docs/conf.py +=================================================================== +--- python-jsonschema.orig/docs/conf.py ++++ python-jsonschema/docs/conf.py +@@ -22,11 +22,8 @@ extensions = [ + "sphinx.ext.autosectionlabel", "sphinx.ext.coverage", "sphinx.ext.doctest", - "sphinx.ext.intersphinx", diff -Nru python-jsonschema-3.2.0/debian/patches/series python-jsonschema-4.6.0/debian/patches/series --- python-jsonschema-3.2.0/debian/patches/series 2020-01-23 15:45:13.000000000 +0000 +++ python-jsonschema-4.6.0/debian/patches/series 2022-07-16 20:07:06.000000000 +0000 @@ -1 +1,3 @@ remove-sphinxcontrib.spelling-from-doc-conf.py.patch +fix-lintian-privacy-breach.patch +do-not-use-furo-theme.patch diff -Nru python-jsonschema-3.2.0/debian/rules python-jsonschema-4.6.0/debian/rules --- python-jsonschema-3.2.0/debian/rules 2019-12-09 10:31:53.000000000 +0000 +++ python-jsonschema-4.6.0/debian/rules 2022-07-16 20:07:06.000000000 +0000 @@ -15,6 +15,6 @@ override_dh_sphinxdoc: ifeq (,$(findstring nodoc, $(DEB_BUILD_OPTIONS))) - http_proxy=127.0.0.1:9 https_proxy=127.0.0.1:9 HTTP_PROXY=127.0.0.1:9 HTTPS_PROXY=127.0.0.1:9 PYTHONPATH=$(CURDIR) PYTHON=python3 python3 -m sphinx $(SPHINXOPTS) -b html docs $(CURDIR)/debian/python-jsonschema-doc/usr/share/doc/python-jsonschema-doc/html + http_proxy=127.0.0.1:9 https_proxy=127.0.0.1:9 HTTP_PROXY=127.0.0.1:9 HTTPS_PROXY=127.0.0.1:9 PYTHONPATH=$(CURDIR)/.pybuild/cpython3_$(shell py3versions -vd)_jsonschema/build PYTHON=python3 python3 -m sphinx $(SPHINXOPTS) -b html docs $(CURDIR)/debian/python-jsonschema-doc/usr/share/doc/python-jsonschema-doc/html dh_sphinxdoc endif diff -Nru python-jsonschema-3.2.0/debian/tests/control python-jsonschema-4.6.0/debian/tests/control --- python-jsonschema-3.2.0/debian/tests/control 2019-12-09 10:31:53.000000000 +0000 +++ python-jsonschema-4.6.0/debian/tests/control 2022-07-16 20:07:06.000000000 +0000 @@ -6,4 +6,5 @@ python3-pyrsistent, python3-pytest, python3-twisted, + python3-pip, @, diff -Nru python-jsonschema-3.2.0/DEMO.ipynb python-jsonschema-4.6.0/DEMO.ipynb --- python-jsonschema-3.2.0/DEMO.ipynb 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/DEMO.ipynb 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# jsonschema\n", - "---" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`jsonschema` is an implementation of [JSON Schema](https://json-schema.org) for Python (supporting 2.7+ including Python 3)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Usage" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from jsonschema import validate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# A sample schema, like what we'd get from json.load()\n", - "schema = {\n", - " \"type\" : \"object\",\n", - " \"properties\" : {\n", - " \"price\" : {\"type\" : \"number\"},\n", - " \"name\" : {\"type\" : \"string\"},\n", - " },\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# If no exception is raised by validate(), the instance is valid.\n", - "validate(instance={\"name\" : \"Eggs\", \"price\" : 34.99}, schema=schema)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "ename": "ValidationError", - "evalue": "'Invalid' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['price']:\n {'type': 'number'}\n\nOn instance['price']:\n 'Invalid'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m validate(\n\u001b[1;32m 2\u001b[0m \u001b[0minstance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"name\"\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0;34m\"Eggs\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"price\"\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0;34m\"Invalid\"\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mschema\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m )\n", - "\u001b[0;32m~/Development/jsonschema/jsonschema/validators.py\u001b[0m in \u001b[0;36mvalidate\u001b[0;34m(instance, schema, cls, *args, **kwargs)\u001b[0m\n\u001b[1;32m 899\u001b[0m \u001b[0merror\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_match\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalidator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miter_errors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstance\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0merror\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 901\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merror\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 902\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValidationError\u001b[0m: 'Invalid' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['price']:\n {'type': 'number'}\n\nOn instance['price']:\n 'Invalid'" - ] - } - ], - "source": [ - "validate(\n", - " instance={\"name\" : \"Eggs\", \"price\" : \"Invalid\"},\n", - " schema=schema,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It can also be used from console:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!echo '{\"name\" : \"Eggs\", \"price\" : 34.99}' > /tmp/sample.json" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!echo '{\"type\" : \"object\", \"properties\" : {\"price\" : {\"type\" : \"number\"}, \"name\" : {\"type\" : \"string\"}}}' > /tmp/sample.schema" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "!jsonschema -i /tmp/sample.json /tmp/sample.schema" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Do your own experiments here..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Try `jsonschema` youself by adding your code below and running your own experiments 👇" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import jsonschema\n", - "\n", - "# your code here\n", - "jsonschema." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.4" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff -Nru python-jsonschema-3.2.0/demo.yml python-jsonschema-4.6.0/demo.yml --- python-jsonschema-3.2.0/demo.yml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/demo.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -requirements: - - jsonschema==3.0.1 diff -Nru python-jsonschema-3.2.0/docs/conf.py python-jsonschema-4.6.0/docs/conf.py --- python-jsonschema-3.2.0/docs/conf.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/conf.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,30 +1,25 @@ -# -*- coding: utf-8 -*- -# -# This file is execfile()d with the current directory set to its containing dir. - -from textwrap import dedent +from importlib import metadata import os import re import sys -import jsonschema - - # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. ext_paths = [os.path.abspath(os.path.pardir), os.path.dirname(__file__)] sys.path = ext_paths + sys.path -# -- General configuration ----------------------------------------------------- +# -- General configuration ------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = "1.0" -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named "sphinx.ext.*") or your custom ones. +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named "sphinx.ext.*") or your custom +# ones. extensions = [ "sphinx.ext.autodoc", + "sphinx.ext.autosectionlabel", "sphinx.ext.coverage", "sphinx.ext.doctest", "sphinx.ext.intersphinx", @@ -49,9 +44,9 @@ master_doc = "index" # General information about the project. -project = u"jsonschema" -author = u"Julian Berman" -copyright = u"2013, " + author +project = "jsonschema" +author = "Julian Berman" +copyright = "2013, " + author # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -59,7 +54,7 @@ # # version: The short X.Y version # release: The full version, including alpha/beta/rc tags. -release = jsonschema.__version__ +release = metadata.version("jsonschema") version = release.partition("-")[0] # There are two options for replacing |today|: either, you set today to some @@ -72,7 +67,7 @@ # directories to ignore when looking for source files. exclude_patterns = ["_build", "_cache", "_static", "_templates"] -# The reST default role (used for this markup: `text`) to use for all documents. +# The reST default role (used for this markup: `text`) to use for all documents default_role = "any" # The name of the Pygments (syntax highlighting) style to use. @@ -81,28 +76,25 @@ # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] -doctest_global_setup = dedent( - """ - from __future__ import print_function - from jsonschema import * +doctest_global_setup = """ +from jsonschema import * """ -) intersphinx_mapping = { - "python": ("https://docs.python.org/2.7", None), - "python3": ("https://docs.python.org/3", None), + "python": ("https://docs.python.org/3", None), } -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output ----------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "pyramid" +html_theme = "furo" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. +# # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. @@ -174,12 +166,12 @@ htmlhelp_basename = "jsonschemadoc" -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output ---------------------------------------------- -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). +# Grouping the document tree into LaTeX files. List of tuples (source +# start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ("index", "jsonschema.tex", u"jsonschema Documentation", author, "manual"), + ("index", "jsonschema.tex", "jsonschema Documentation", author, "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -203,17 +195,17 @@ # latex_domain_indices = True -# -- Options for manual page output -------------------------------------------- +# -- Options for manual page output ---------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [("index", "jsonschema", u"jsonschema Documentation", [author], 1)] +man_pages = [("index", "jsonschema", "jsonschema Documentation", [author], 1)] # If true, show URL addresses after external links. # man_show_urls = False -# -- Options for Texinfo output ------------------------------------------------ +# -- Options for Texinfo output -------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, @@ -222,7 +214,7 @@ ( "index", "jsonschema", - u"jsonschema Documentation", + "jsonschema Documentation", author, "jsonschema", "One line description of project.", @@ -246,7 +238,15 @@ return r"http.?://" + re.escape(host) + r"($|/.*)" -linkcheck_ignore = [entire_domain("codecov.io")] +linkcheck_ignore = [ + entire_domain("img.shields.io"), + "https://github.com/python-jsonschema/jsonschema/actions", + "https://github.com/python-jsonschema/jsonschema/workflows/CI/badge.svg", +] + +# -- Options for sphinxcontrib-autosectionlabel --------------------------- + +autosectionlabel_prefix_document = True # -- Options for sphinxcontrib-spelling ----------------------------------- diff -Nru python-jsonschema-3.2.0/docs/creating.rst python-jsonschema-4.6.0/docs/creating.rst --- python-jsonschema-3.2.0/docs/creating.rst 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/creating.rst 2022-06-01 20:26:26.000000000 +0000 @@ -23,3 +23,12 @@ instance, or schema, it should pass one or both of the ``path`` or ``schema_path`` arguments to ``descend`` in order to properly maintain where in the instance or schema respectively the error occurred. + +The Validator Protocol +---------------------- + +``jsonschema`` defines a `protocol `, +`jsonschema.protocols.Validator` which can be used in type annotations to +describe the type of a validator object. + +For full details, see `validator-protocol`. diff -Nru python-jsonschema-3.2.0/docs/errors.rst python-jsonschema-4.6.0/docs/errors.rst --- python-jsonschema-3.2.0/docs/errors.rst 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/errors.rst 2022-06-01 20:26:26.000000000 +0000 @@ -16,7 +16,9 @@ =============== ================= ======================== `message` `context` `instance` - `cause` `path` + `cause` `json_path` + + `path` `schema` @@ -79,6 +81,11 @@ `instance`\). The deque can be empty if the error happened at the root of the instance. + .. attribute:: json_path + + A `JSON path `_ + to the offending element within the instance. + .. attribute:: path Same as `relative_path`. @@ -268,7 +275,7 @@ As you can see, `jsonschema.exceptions.ErrorTree` takes an iterable of `ValidationError`\s when constructing a tree so you can directly pass it the return value of a validator object's -`jsonschema.IValidator.iter_errors` method. +`jsonschema.protocols.Validator.iter_errors` method. `ErrorTree`\s support a number of useful operations. The first one we might want to perform is to check whether a given element in our instance diff -Nru python-jsonschema-3.2.0/docs/faq.rst python-jsonschema-4.6.0/docs/faq.rst --- python-jsonschema-3.2.0/docs/faq.rst 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/faq.rst 2022-06-01 20:26:26.000000000 +0000 @@ -3,6 +3,77 @@ ========================== +My schema specifies format validation. Why do invalid instances seem valid? +--------------------------------------------------------------------------- + +The :validator:`format` validator can be a bit of a stumbling block for new +users working with JSON Schema. + +In a schema such as: + +.. code-block:: json + + {"type": "string", "format": "date"} + +JSON Schema specifications have historically differentiated between the +:validator:`format` validator and other validators. In particular, the +:validator:`format` validator was specified to be *informational* as much +as it may be used for validation. + +In other words, for many use cases, schema authors may wish to use +values for the :validator:`format` validator but have no expectation +they be validated alongside other required assertions in a schema. + +Of course this does not represent all or even most use cases -- many +schema authors *do* wish to assert that instances conform fully, even to +the specific format mentioned. + +In drafts prior to ``draft2019-09``, the decision on whether to +automatically enable :validator:`format` validation was left up to +validation implementations such as this one. + +This library made the choice to leave it off by default, for two reasons: + + * for forward compatibility and implementation complexity reasons + -- if :validator:`format` validation were on by default, and a + future draft of JSON Schema introduced a hard-to-implement format, + either the implementation of that format would block releases of + this library until it were implemented, or the behavior surrounding + :validator:`format` would need to be even more complex than simply + defaulting to be on. It therefore was safer to start with it off, + and defend against the expectation that a given format would always + automatically work. + + * given that a common use of JSON Schema is for portability across + languages (and therefore implementations of JSON Schema), so that + users be aware of this point itself regarding :validator:`format` + validation, and therefore remember to check any *other* + implementations they were using to ensure they too were explicitly + enabled for :validator:`format` validation. + +As of ``draft2019-09`` however, the opt-out by default behavior +mentioned here is now *required* for all validators. + +Difficult as this may sound for new users, at this point it at least +means they should expect the same behavior that has always been +implemented here, across any other implementation they encounter. + +.. seealso:: + + `Draft 2019-09's release notes on format `_ + + for upstream details on the behavior of format and how it has changed + in ``draft2019-09`` + + `validating formats` + + for details on how to enable format validation + + `jsonschema.FormatChecker` + + the object which implements format validation + + Why doesn't my schema's default property set the default on my instance? ------------------------------------------------------------------------ @@ -19,8 +90,8 @@ Still, filling in defaults is a thing that is useful. `jsonschema` allows you to `define your own validator classes and callables -`, so you can easily create an `jsonschema.IValidator` that -does do default setting. Here's some code to get you started. (In +`, so you can easily create an `jsonschema.protocols.Validator` +that does do default setting. Here's some code to get you started. (In this code, we add the default properties to each object *before* the properties are validated, so the default values themselves will need to be valid under the schema.) @@ -138,11 +209,12 @@ The following are *not* considered public API and may change without notice: - * the exact wording and contents of error messages; typical - reasons to do this seem to involve unit tests. API users are - encouraged to use the extensive introspection provided in - `jsonschema.exceptions.ValidationError`\s instead to make meaningful - assertions about what failed. + * the exact wording and contents of error messages; typical reasons + to rely on this seem to involve downstream tests in packages using + `jsonschema`. These use cases are encouraged to use the extensive + introspection provided in `jsonschema.exceptions.ValidationError`\s + instead to make meaningful assertions about what failed rather than + relying on *how* what failed is explained to a human. * the order in which validation errors are returned or raised @@ -150,8 +222,12 @@ * the contents of the ``jsonschema.benchmarks`` package - * the ``jsonschema.compat`` module, which is for internal - compatibility use + * the specific non-zero error codes presented by the command line + interface + + * the exact representation of errors presented by the command line + interface, other than that errors represented by the plain outputter + will be reported one per line * anything marked private diff -Nru python-jsonschema-3.2.0/docs/jsonschema_role.py python-jsonschema-4.6.0/docs/jsonschema_role.py --- python-jsonschema-3.2.0/docs/jsonschema_role.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/jsonschema_role.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,19 +1,20 @@ +from contextlib import suppress from datetime import datetime -from docutils import nodes -import errno +from importlib import metadata +from urllib.parse import urljoin import os +import urllib.request -try: - import urllib2 as urllib -except ImportError: - import urllib.request as urllib - -import certifi +from docutils import nodes from lxml import html +import certifi +__version__ = "1.2.0" -__version__ = "1.0.0" -VALIDATION_SPEC = "https://json-schema.org/draft-07/json-schema-validation.html" +BASE_URL = "https://json-schema.org/draft-07/" +VALIDATION_SPEC = urljoin(BASE_URL, "json-schema-validation.html") +REF_URL = urljoin(BASE_URL, "json-schema-core.html#rfc.section.8.3") +SCHEMA_URL = urljoin(BASE_URL, "json-schema-core.html#rfc.section.7") def setup(app): @@ -29,15 +30,11 @@ app.add_config_value("cache_path", "_cache", "") - try: - os.makedirs(app.config.cache_path) - except OSError as error: - if error.errno != errno.EEXIST: - raise + os.makedirs(app.config.cache_path, exist_ok=True) path = os.path.join(app.config.cache_path, "spec.html") spec = fetch_or_load(path) - app.add_role("validator", docutils_sucks(spec)) + app.add_role("validator", docutils_does_not_allow_using_classes(spec)) return dict(version=__version__, parallel_read_safe=True) @@ -53,18 +50,20 @@ the path to a cached specification """ - headers = {} + headers = { + "User-Agent": "python-jsonschema v{} - documentation build v{}".format( + metadata.version("jsonschema"), + __version__, + ), + } - try: + with suppress(FileNotFoundError): modified = datetime.utcfromtimestamp(os.path.getmtime(spec_path)) date = modified.strftime("%a, %d %b %Y %I:%M:%S UTC") headers["If-Modified-Since"] = date - except OSError as error: - if error.errno != errno.ENOENT: - raise - request = urllib.Request(VALIDATION_SPEC, headers=headers) - response = urllib.urlopen(request, cafile=certifi.where()) + request = urllib.request.Request(VALIDATION_SPEC, headers=headers) + response = urllib.request.urlopen(request, cafile=certifi.where()) if response.code == 200: with open(spec_path, "w+b") as spec: @@ -76,18 +75,15 @@ return html.parse(spec) -def docutils_sucks(spec): +def docutils_does_not_allow_using_classes(spec): """ Yeah. - It doesn't allow using a class because it does stupid stuff like try to set - attributes on the callable object rather than just keeping a dict. + It doesn't allow using a class because it does annoying stuff like + try to set attributes on the callable object rather than just + keeping a dict. """ - base_url = VALIDATION_SPEC - ref_url = "https://json-schema.org/draft-07/json-schema-core.html#rfc.section.8.3" - schema_url = "https://json-schema.org/draft-07/json-schema-core.html#rfc.section.7" - def validator(name, raw_text, text, lineno, inliner): """ Link to the JSON Schema documentation for a validator. @@ -123,9 +119,9 @@ """ if text == "$ref": - return [nodes.reference(raw_text, text, refuri=ref_url)], [] + return [nodes.reference(raw_text, text, refuri=REF_URL)], [] elif text == "$schema": - return [nodes.reference(raw_text, text, refuri=schema_url)], [] + return [nodes.reference(raw_text, text, refuri=SCHEMA_URL)], [] # find the header in the validation spec containing matching text header = spec.xpath("//h1[contains(text(), '{0}')]".format(text)) @@ -134,7 +130,7 @@ inliner.reporter.warning( "Didn't find a target for {0}".format(text), ) - uri = base_url + uri = VALIDATION_SPEC else: if len(header) > 1: inliner.reporter.info( @@ -142,7 +138,7 @@ ) # get the href from link in the header - uri = base_url + header[0].find("a").attrib["href"] + uri = urljoin(VALIDATION_SPEC, header[0].find("a").attrib["href"]) reference = nodes.reference(raw_text, text, refuri=uri) return [reference], [] diff -Nru python-jsonschema-3.2.0/docs/requirements.in python-jsonschema-4.6.0/docs/requirements.in --- python-jsonschema-3.2.0/docs/requirements.in 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/requirements.in 2022-06-01 20:26:26.000000000 +0000 @@ -1,3 +1,5 @@ +file:.#egg=jsonschema +furo lxml sphinx sphinxcontrib-spelling diff -Nru python-jsonschema-3.2.0/docs/requirements.txt python-jsonschema-4.6.0/docs/requirements.txt --- python-jsonschema-3.2.0/docs/requirements.txt 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/requirements.txt 2022-06-01 20:26:26.000000000 +0000 @@ -1,36 +1,75 @@ # -# This file is autogenerated by pip-compile +# This file is autogenerated by pip-compile with python 3.10 # To update, run: # -# pip-compile requirements.in +# pip-compile docs/requirements.in # -alabaster==0.7.12 # via sphinx -babel==2.7.0 # via sphinx -certifi==2019.9.11 # via requests -chardet==3.0.4 # via requests -docutils==0.15.2 # via sphinx -idna==2.8 # via requests -imagesize==1.1.0 # via sphinx -jinja2==2.10.3 # via sphinx -lxml==4.4.1 -markupsafe==1.1.1 # via jinja2 -packaging==19.2 # via sphinx -pyenchant==2.0.0 # via sphinxcontrib-spelling -pygments==2.4.2 # via sphinx -pyparsing==2.4.4 # via packaging -pytz==2019.3 # via babel -requests==2.22.0 # via sphinx -six==1.13.0 # via packaging, sphinxcontrib-spelling -snowballstemmer==2.0.0 # via sphinx -sphinx==2.2.1 -sphinxcontrib-applehelp==1.0.1 # via sphinx -sphinxcontrib-devhelp==1.0.1 # via sphinx -sphinxcontrib-htmlhelp==1.0.2 # via sphinx -sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.2 # via sphinx -sphinxcontrib-serializinghtml==1.1.3 # via sphinx -sphinxcontrib-spelling==4.3.0 -urllib3==1.25.6 # via requests - -# The following packages are considered to be unsafe in a requirements file: -# setuptools==41.6.0 # via sphinx +alabaster==0.7.12 + # via sphinx +attrs==21.4.0 + # via jsonschema +babel==2.10.1 + # via sphinx +beautifulsoup4==4.11.1 + # via furo +certifi==2022.5.18.1 + # via requests +charset-normalizer==2.0.12 + # via requests +docutils==0.17.1 + # via sphinx +furo==2022.4.7 + # via -r docs/requirements.in +idna==3.3 + # via requests +imagesize==1.3.0 + # via sphinx +jinja2==3.1.2 + # via sphinx +file:.#egg=jsonschema + # via -r docs/requirements.in +lxml==4.8.0 + # via -r docs/requirements.in +markupsafe==2.1.1 + # via jinja2 +packaging==21.3 + # via sphinx +pyenchant==3.2.2 + # via sphinxcontrib-spelling +pygments==2.12.0 + # via + # furo + # sphinx +pyparsing==3.0.9 + # via packaging +pyrsistent==0.18.1 + # via jsonschema +pytz==2022.1 + # via babel +requests==2.27.1 + # via sphinx +snowballstemmer==2.2.0 + # via sphinx +soupsieve==2.3.2.post1 + # via beautifulsoup4 +sphinx==4.5.0 + # via + # -r docs/requirements.in + # furo + # sphinxcontrib-spelling +sphinxcontrib-applehelp==1.0.2 + # via sphinx +sphinxcontrib-devhelp==1.0.2 + # via sphinx +sphinxcontrib-htmlhelp==2.0.0 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-qthelp==1.0.3 + # via sphinx +sphinxcontrib-serializinghtml==1.1.5 + # via sphinx +sphinxcontrib-spelling==7.4.1 + # via -r docs/requirements.in +urllib3==1.26.9 + # via requests diff -Nru python-jsonschema-3.2.0/docs/spelling-wordlist.txt python-jsonschema-4.6.0/docs/spelling-wordlist.txt --- python-jsonschema-3.2.0/docs/spelling-wordlist.txt 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/spelling-wordlist.txt 2022-06-01 20:26:26.000000000 +0000 @@ -1,5 +1,5 @@ # this appears to be misinterpreting Napoleon types as prose, sigh... -IValidator +Validator TypeChecker UnknownType ValidationError @@ -20,10 +20,12 @@ majorly metaschema online +outputter pre programmatically recurses regex +repr sensical subschema subschemas @@ -38,5 +40,5 @@ HD Berman -Freenode +Libera GPL diff -Nru python-jsonschema-3.2.0/docs/validate.rst python-jsonschema-4.6.0/docs/validate.rst --- python-jsonschema-3.2.0/docs/validate.rst 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/docs/validate.rst 2022-06-01 20:26:26.000000000 +0000 @@ -19,148 +19,26 @@ fundamentals underway at `Understanding JSON Schema `_ +.. _validator-protocol: -The Validator Interface +The Validator Protocol ----------------------- -`jsonschema` defines an (informal) interface that all validator +`jsonschema` defines a protocol that all validator classes should adhere to. -.. class:: IValidator(schema, types=(), resolver=None, format_checker=None) - - :argument dict schema: the schema that the validator object - will validate with. It is assumed to be valid, and providing - an invalid schema can lead to undefined behavior. See - `IValidator.check_schema` to validate a schema first. - :argument resolver: an instance of `RefResolver` that will be - used to resolve :validator:`$ref` properties (JSON references). If - unprovided, one will be created. - :argument format_checker: an instance of `FormatChecker` - whose `FormatChecker.conforms` method will be called to - check and see if instances conform to each :validator:`format` - property present in the schema. If unprovided, no validation - will be done for :validator:`format`. Certain formats require - additional packages to be installed (ipv5, uri, color, date-time). - The required packages can be found at the bottom of this page. - :argument types: - .. deprecated:: 3.0.0 - - Use `TypeChecker.redefine` and - `jsonschema.validators.extend` instead of this argument. - - See `validating-types` for details. - - If used, this overrides or extends the list of known types when - validating the :validator:`type` property. - - What is provided should map strings (type names) to class objects - that will be checked via `isinstance`. - - - .. attribute:: META_SCHEMA - - An object representing the validator's meta schema (the schema that - describes valid schemas in the given version). - - .. attribute:: VALIDATORS - - A mapping of validator names (`str`\s) to functions - that validate the validator property with that name. For more - information see `creating-validators`. - - .. attribute:: TYPE_CHECKER - - A `TypeChecker` that will be used when validating :validator:`type` - properties in JSON schemas. - - .. attribute:: schema - - The schema that was passed in when initializing the object. - - .. attribute:: DEFAULT_TYPES - - .. deprecated:: 3.0.0 - - Use of this attribute is deprecated in favor of the new `type - checkers `. - - See `validating-types` for details. - - For backwards compatibility on existing validator classes, a mapping of - JSON types to Python class objects which define the Python types for - each JSON type. - - Any existing code using this attribute should likely transition to - using `TypeChecker.is_type`. - - - .. classmethod:: check_schema(schema) - - Validate the given schema against the validator's `META_SCHEMA`. - - :raises: `jsonschema.exceptions.SchemaError` if the schema - is invalid - - .. method:: is_type(instance, type) - - Check if the instance is of the given (JSON Schema) type. - - :type type: str - :rtype: bool - :raises: `jsonschema.exceptions.UnknownType` if ``type`` - is not a known type. - - .. method:: is_valid(instance) - - Check if the instance is valid under the current `schema`. - - :rtype: bool - - >>> schema = {"maxItems" : 2} - >>> Draft3Validator(schema).is_valid([2, 3, 4]) - False - - .. method:: iter_errors(instance) - - Lazily yield each of the validation errors in the given instance. - - :rtype: an `collections.Iterable` of - `jsonschema.exceptions.ValidationError`\s - - >>> schema = { - ... "type" : "array", - ... "items" : {"enum" : [1, 2, 3]}, - ... "maxItems" : 2, - ... } - >>> v = Draft3Validator(schema) - >>> for error in sorted(v.iter_errors([2, 3, 4]), key=str): - ... print(error.message) - 4 is not one of [1, 2, 3] - [2, 3, 4] is too long - - .. method:: validate(instance) - - Check if the instance is valid under the current `schema`. - - :raises: `jsonschema.exceptions.ValidationError` if the - instance is invalid - - >>> schema = {"maxItems" : 2} - >>> Draft3Validator(schema).validate([2, 3, 4]) - Traceback (most recent call last): - ... - ValidationError: [2, 3, 4] is too long - +.. autoclass:: jsonschema.protocols.Validator + :members: All of the `versioned validators ` that are included with -`jsonschema` adhere to the interface, and implementers of validator classes +`jsonschema` adhere to the protocol, and implementers of validator classes that extend or complement the ones included should adhere to it as well. For more information see `creating-validators`. Type Checking ------------- -To handle JSON Schema's :validator:`type` property, a `IValidator` uses +To handle JSON Schema's :validator:`type` property, a `Validator` uses an associated `TypeChecker`. The type checker provides an immutable mapping between names of types and functions that can test if an instance is of that type. The defaults are suitable for most users - each of the @@ -204,7 +82,7 @@ If you *do* want the generality, or just want to add a few specific additional types as being acceptable for a validator object, then you should update an existing `TypeChecker` or create a new one. You may then create a new -`IValidator` via `jsonschema.validators.extend`. +`Validator` via `jsonschema.validators.extend`. .. code-block:: python @@ -232,9 +110,13 @@ `jsonschema` ships with validator classes for various versions of the JSON Schema specification. For details on the methods and attributes -that each validator class provides see the `IValidator` interface, +that each validator class provides see the `Validator` protocol, which each included validator class implements. +.. autoclass:: Draft202012Validator + +.. autoclass:: Draft201909Validator + .. autoclass:: Draft7Validator .. autoclass:: Draft6Validator @@ -245,14 +127,14 @@ For example, if you wanted to validate a schema you created against the -Draft 6 meta-schema, you could use: +Draft 7 meta-schema, you could use: .. code-block:: python - from jsonschema import Draft6Validator + from jsonschema import Draft7Validator schema = { - "$schema": "https://json-schema.org/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { @@ -261,8 +143,10 @@ }, "required": ["email"] } - Draft6Validator.check_schema(schema) + Draft7Validator.check_schema(schema) + +.. _validating formats: Validating Formats ------------------ @@ -271,19 +155,19 @@ if primitive types (``string``\s, ``number``\s, ``boolean``\s) conform to well-defined formats. By default, no validation is enforced, but optionally, validation can be enabled by hooking in a format-checking object into an -`IValidator`. +`Validator`. .. doctest:: - >>> validate("localhost", {"format" : "hostname"}) + >>> validate("127.0.0.1", {"format" : "ipv4"}) >>> validate( ... instance="-12", - ... schema={"format" : "hostname"}, + ... schema={"format" : "ipv4"}, ... format_checker=draft7_format_checker, ... ) Traceback (most recent call last): ... - ValidationError: "-12" is not a "hostname" + ValidationError: "-12" is not a "ipv4" .. autoclass:: FormatChecker :members: @@ -321,7 +205,7 @@ `FormatChecker.checkers` attribute. Certain checkers will only be available if an appropriate package is available for use. The easiest way to ensure you have what is needed is to install ``jsonschema`` using the -``format`` or ``format_nongpl`` setuptools extra -- i.e. +``format`` or ``format_nongpl`` collection of optional dependencies -- e.g. .. code-block:: sh @@ -354,9 +238,10 @@ ========================= ==================== ``color`` requires webcolors_ ``date`` -``date-time`` requires strict-rfc3339_ or rfc3339-validator_ +``date-time`` requires rfc3339-validator_ +``duration`` requires isoduration_ ``email`` -``hostname`` +``hostname`` requires fqdn_ ``idn-hostname`` requires idna_ ``ipv4`` ``ipv6`` OS must have `socket.inet_pton` function @@ -365,20 +250,23 @@ ``json-pointer`` requires jsonpointer_ ``regex`` ``relative-json-pointer`` requires jsonpointer_ -``time`` requires strict-rfc3339_ or rfc3339-validator_ +``time`` requires rfc3339-validator_ ``uri`` requires rfc3987_ or rfc3986-validator_ ``uri-reference`` requires rfc3987_ or rfc3986-validator_ +``uri-template`` requires uri-template_ ========================= ==================== +.. _fqdn: https://pypi.org/pypi/fqdn/ .. _idna: https://pypi.org/pypi/idna/ +.. _isoduration: https://pypi.org/pypi/isoduration/ .. _jsonpointer: https://pypi.org/pypi/jsonpointer/ +.. _rfc3339-validator: https://pypi.org/project/rfc3339-validator/ +.. _rfc3986-validator: https://pypi.org/project/rfc3986-validator/ .. _rfc3987: https://pypi.org/pypi/rfc3987/ .. _rfc5322: https://tools.ietf.org/html/rfc5322#section-3.4.1 -.. _strict-rfc3339: https://pypi.org/pypi/strict-rfc3339/ +.. _uri-template: https://pypi.org/pypi/uri-template/ .. _webcolors: https://pypi.org/pypi/webcolors/ -.. _rfc3339-validator: https://pypi.org/project/rfc3339-validator/ -.. _rfc3986-validator: https://pypi.org/project/rfc3986-validator/ .. note:: diff -Nru python-jsonschema-3.2.0/.flake8 python-jsonschema-4.6.0/.flake8 --- python-jsonschema-3.2.0/.flake8 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.flake8 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,10 @@ +[flake8] +ban-relative-imports = true +inline-quotes = " +exclude = + jsonschema/__init__.py + jsonschema/_reflect.py +ignore = + B008, # Barring function calls in default args. Ha, no. + B306, # See https://github.com/PyCQA/flake8-bugbear/issues/131 + W503, # (flake8 default) old PEP8 boolean operator line breaks diff -Nru python-jsonschema-3.2.0/.github/FUNDING.yml python-jsonschema-4.6.0/.github/FUNDING.yml --- python-jsonschema-3.2.0/.github/FUNDING.yml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/.github/FUNDING.yml 2022-06-01 20:26:26.000000000 +0000 @@ -1,5 +1,4 @@ # These are supported funding model platforms github: "Julian" -patreon: "JulianWasTaken" tidelift: "pypi/jsonschema" diff -Nru python-jsonschema-3.2.0/.github/workflows/ci.yml python-jsonschema-4.6.0/.github/workflows/ci.yml --- python-jsonschema-3.2.0/.github/workflows/ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.github/workflows/ci.yml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,234 @@ +name: CI + +on: + push: + pull_request: + release: + types: [published] + schedule: + # Daily at 3:21 + - cron: '21 3 * * *' + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v2.0.3 + + ci: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + python-version: + - name: pypy-3.8 + toxenv: pypy3-noextra-build + - name: pypy-3.8 + toxenv: pypy3-noextra-tests + - name: pypy-3.8 + toxenv: pypy3-format-build + - name: pypy-3.8 + toxenv: pypy3-format-tests + - name: pypy-3.8 + toxenv: pypy3-format_nongpl-build + - name: pypy-3.8 + toxenv: pypy3-format_nongpl-tests + - name: 3.7 + toxenv: py37-noextra-build + - name: 3.7 + toxenv: py37-noextra-tests + - name: 3.7 + toxenv: py37-format-build + - name: 3.7 + toxenv: py37-format-tests + - name: 3.7 + toxenv: py37-format_nongpl-build + - name: 3.7 + toxenv: py37-format_nongpl-tests + - name: 3.8 + toxenv: py38-noextra-build + - name: 3.8 + toxenv: py38-noextra-tests + - name: 3.8 + toxenv: py38-format-build + - name: 3.8 + toxenv: py38-format-tests + - name: 3.8 + toxenv: py38-format_nongpl-build + - name: 3.8 + toxenv: py38-format_nongpl-tests + - name: 3.9 + toxenv: py39-noextra-build + - name: 3.9 + toxenv: py39-noextra-tests + - name: 3.9 + toxenv: py39-format-build + - name: 3.9 + toxenv: py39-format-tests + - name: 3.9 + toxenv: py39-format_nongpl-build + - name: 3.9 + toxenv: py39-format_nongpl-tests + - name: "3.10" + toxenv: py310-noextra-build + - name: "3.10" + toxenv: py310-noextra-tests + - name: "3.10" + toxenv: py310-format-build + - name: "3.10" + toxenv: py310-format-tests + - name: "3.10" + toxenv: py310-format_nongpl-build + - name: "3.10" + toxenv: py310-format_nongpl-tests + - name: "3.11.0-beta - 3.11.0" + toxenv: py311-noextra-build + - name: "3.11.0-beta - 3.11.0" + toxenv: py311-noextra-tests + - name: "3.11.0-beta - 3.11.0" + toxenv: py311-format-build + - name: "3.11.0-beta - 3.11.0" + toxenv: py311-format-tests + - name: "3.11.0-beta - 3.11.0" + toxenv: py311-format_nongpl-build + - name: "3.11.0-beta - 3.11.0" + toxenv: py311-format_nongpl-tests + - name: "3.10" + toxenv: docs-dirhtml + - name: "3.10" + toxenv: docs-doctest + - name: "3.10" + toxenv: docs-linkcheck + - name: "3.10" + toxenv: docs-spelling + - name: "3.10" + toxenv: docs-style + - name: "3.10" + toxenv: readme + - name: "3.10" + toxenv: safety + - name: "3.10" + toxenv: secrets + - name: "3.10" + toxenv: style + - name: "3.10" + toxenv: typing + exclude: + - os: windows-latest + python-version: + name: pypy-3.8 + toxenv: pypy3-noextra-build + - os: windows-latest + python-version: + name: pypy-3.8 + toxenv: pypy3-noextra-tests + - os: windows-latest + python-version: + name: pypy-3.8 + toxenv: pypy3-format-build + - os: windows-latest + python-version: + name: pypy-3.8 + toxenv: pypy3-format-tests + - os: windows-latest + python-version: + name: pypy-3.8 + toxenv: pypy3-format_nongpl-build + - os: windows-latest + python-version: + name: pypy-3.8 + toxenv: pypy3-format_nongpl-tests + - os: windows-latest + python-version: + name: "3.10" + toxenv: py310-noextra-tests + - os: windows-latest + python-version: + name: "3.10" + toxenv: py310-format-tests + - os: windows-latest + python-version: + name: "3.10" + toxenv: py310-format_nongpl-tests + - os: windows-latest + python-version: + name: "3.11.0-alpha - 3.11.0" + toxenv: py311-noextra-tests + - os: windows-latest + python-version: + name: "3.11.0-alpha - 3.11.0" + toxenv: py311-format-tests + - os: windows-latest + python-version: + name: "3.11.0-alpha - 3.11.0" + toxenv: py311-format_nongpl-tests + - os: windows-latest + python-version: + name: "3.10" + toxenv: readme + - os: windows-latest + python-version: + name: "3.10" + toxenv: docs-linkcheck + - os: windows-latest + python-version: + name: "3.10" + toxenv: docs-style + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version.name }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version.name }} + - name: Install dependencies + run: > + sudo apt-get update && + sudo apt-get install -y libenchant-dev libxml2-dev libxslt-dev + if: runner.os == 'Linux' && startsWith(matrix.python-version.toxenv, 'docs-') + - name: Install dependencies + run: brew install enchant + if: runner.os == 'macOS' && startsWith(matrix.python-version.toxenv, 'docs-') + - name: Install tox + run: python -m pip install tox + - name: Run tox + run: python -m tox -e "${{ matrix.python-version.toxenv }}" + + packaging: + needs: ci + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install dependencies + run: python -m pip install build + - name: Create packages + run: python -m build . + - uses: actions/upload-artifact@v3 + with: + name: dist + path: dist + - name: Publish package + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.pypi_password }} + - name: Create Release Notes + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + await github.request(`POST /repos/${{ github.repository }}/releases`, { + tag_name: "${{ github.ref }}", + generate_release_notes: true + }); diff -Nru python-jsonschema-3.2.0/.github/workflows/coverage.yml python-jsonschema-4.6.0/.github/workflows/coverage.yml --- python-jsonschema-3.2.0/.github/workflows/coverage.yml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.github/workflows/coverage.yml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,25 @@ +name: Coverage + +on: + push: + pull_request: + release: + types: [published] + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install tox + run: python -m pip install tox + - name: Collect & Upload Coverage + # codecov.io is too flaky to fail for this right now + continue-on-error: true + run: python -m tox -e py39-format-codecov + env: + CODECOV_TOKEN: 2b38dae1-41c4-4435-a29d-79a1299e5617 diff -Nru python-jsonschema-3.2.0/.github/workflows/fuzz.yml python-jsonschema-4.6.0/.github/workflows/fuzz.yml --- python-jsonschema-3.2.0/.github/workflows/fuzz.yml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.github/workflows/fuzz.yml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,30 @@ +name: CIFuzz + +on: + pull_request: + branches: + - main + +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'jsonschema' + language: python + continue-on-error: true + - name: Run Fuzzers + if: steps.build.outcome == 'success' + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'jsonschema' + fuzz-seconds: 30 + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts diff -Nru python-jsonschema-3.2.0/.gitignore python-jsonschema-4.6.0/.gitignore --- python-jsonschema-3.2.0/.gitignore 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/.gitignore 2022-06-01 20:26:26.000000000 +0000 @@ -1,5 +1,157 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# User defined _cache _static _templates - -TODO diff -Nru python-jsonschema-3.2.0/json/bin/jsonschema_suite python-jsonschema-4.6.0/json/bin/jsonschema_suite --- python-jsonschema-3.2.0/json/bin/jsonschema_suite 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/bin/jsonschema_suite 2022-06-01 20:26:26.000000000 +0000 @@ -1,6 +1,4 @@ #! /usr/bin/env python3 -from __future__ import print_function -from pprint import pformat import argparse import errno import fnmatch @@ -13,62 +11,44 @@ import unittest import warnings -if getattr(unittest, "skipIf", None) is None: - unittest.skipIf = lambda cond, msg : lambda fn : fn - try: - import jsonschema + import jsonschema.validators except ImportError: jsonschema = None -else: - validators = getattr( - jsonschema.validators, "validators", jsonschema.validators - ) ROOT_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir).rstrip("__pycache__"), ) SUITE_ROOT_DIR = os.path.join(ROOT_DIR, "tests") - -REMOTES = { - "integer.json": {u"type": u"integer"}, - "name.json": { - u"type": "string", - u"definitions": { - u"orNull": {u"anyOf": [{u"type": u"null"}, {u"$ref": u"#"}]}, - }, - }, - "name-defs.json": { - u"type": "string", - u"$defs": { - u"orNull": {u"anyOf": [{u"type": u"null"}, {u"$ref": u"#"}]}, - }, - }, - "subSchemas.json": { - u"integer": {u"type": u"integer"}, - u"refToInteger": {u"$ref": u"#/integer"}, - }, - "folder/folderInteger.json": {u"type": u"integer"} -} REMOTES_DIR = os.path.join(ROOT_DIR, "remotes") with open(os.path.join(ROOT_DIR, "test-schema.json")) as schema: TESTSUITE_SCHEMA = json.load(schema) + def files(paths): + """ + Each test file in the provided paths. + """ for path in paths: with open(path) as test_file: yield json.load(test_file) def groups(paths): + """ + Each test group within each file in the provided paths. + """ for test_file in files(paths): for group in test_file: yield group def cases(paths): + """ + Each individual test case within all groups within the provided paths. + """ for test_group in groups(paths): for test in test_group["tests"]: test["schema"] = test_group["schema"] @@ -76,7 +56,10 @@ def collect(root_dir): - for root, dirs, files in os.walk(root_dir): + """ + All of the test file paths within the given root directory, recursively. + """ + for root, _, files in os.walk(root_dir): for filename in fnmatch.filter(files, "*.json"): yield os.path.join(root, filename) @@ -85,11 +68,15 @@ @classmethod def setUpClass(cls): print("Looking for tests in %s" % SUITE_ROOT_DIR) + print("Looking for remotes in %s" % REMOTES_DIR) cls.test_files = list(collect(SUITE_ROOT_DIR)) + cls.remote_files = list(collect(REMOTES_DIR)) print("Found %s test files" % len(cls.test_files)) + print("Found %s remote files" % len(cls.remote_files)) assert cls.test_files, "Didn't find the test files!" + assert cls.remote_files, "Didn't find the remote files!" - def test_all_files_are_valid_json(self): + def test_all_test_files_are_valid_json(self): for path in self.test_files: with open(path) as test_file: try: @@ -97,6 +84,14 @@ except ValueError as error: self.fail("%s contains invalid JSON (%s)" % (path, error)) + def test_all_remote_files_are_valid_json(self): + for path in self.remote_files: + with open(path) as remote_file: + try: + json.load(remote_file) + except ValueError as error: + self.fail("%s contains invalid JSON (%s)" % (path, error)) + def test_all_descriptions_have_reasonable_length(self): for case in cases(self.test_files): description = case["description"] @@ -120,7 +115,7 @@ @unittest.skipIf(jsonschema is None, "Validation library not present!") def test_all_schemas_are_valid(self): for schema in os.listdir(SUITE_ROOT_DIR): - schema_validator = validators.get(schema) + schema_validator = jsonschema.validators.validators.get(schema) if schema_validator is not None: test_files = collect(os.path.join(SUITE_ROOT_DIR, schema)) for case in cases(test_files): @@ -134,55 +129,14 @@ @unittest.skipIf(jsonschema is None, "Validation library not present!") def test_suites_are_valid(self): - validator = jsonschema.Draft4Validator(TESTSUITE_SCHEMA) + Validator = jsonschema.validators.validator_for(TESTSUITE_SCHEMA) + validator = Validator(TESTSUITE_SCHEMA) for tests in files(self.test_files): try: validator.validate(tests) except jsonschema.ValidationError as error: self.fail(str(error)) - def test_remote_schemas_are_updated(self): - files = {} - for parent, _, paths in os.walk(REMOTES_DIR): - for path in paths: - absolute_path = os.path.join(parent, path) - with open(absolute_path) as schema_file: - files[absolute_path] = json.load(schema_file) - - expected = { - os.path.join(REMOTES_DIR, path): contents - for path, contents in REMOTES.items() - } - - missing = set(files).symmetric_difference(expected) - changed = { - path - for path, contents in expected.items() - if path in files - and contents != files[path] - } - - self.assertEqual( - files, - expected, - msg=textwrap.dedent( - """ - Remotes in the remotes/ directory do not match those in the - ``jsonschema_suite`` Python script. - - Unfortunately for the minute, each remote file is duplicated in - two places.""" + (""" - - Only present in one location: - - {}""".format("\n".join(missing)) if missing else "") + (""" - - Conflicting between the two: - - {}""".format("\n".join(changed)) if changed else "") - ) - ) - def main(arguments): if arguments.command == "check": @@ -197,34 +151,26 @@ json.dump(selected_cases, sys.stdout, indent=4, sort_keys=True) elif arguments.command == "remotes": - json.dump(REMOTES, sys.stdout, indent=4, sort_keys=True) + remotes = {} + for path in collect(REMOTES_DIR): + relative_path = os.path.relpath(path, REMOTES_DIR) + with open(path) as schema_file: + remotes[relative_path] = json.load(schema_file) + json.dump(remotes, sys.stdout, indent=4, sort_keys=True) elif arguments.command == "dump_remotes": if arguments.update: shutil.rmtree(arguments.out_dir, ignore_errors=True) try: - os.makedirs(arguments.out_dir) + shutil.copytree(REMOTES_DIR, arguments.out_dir) except OSError as e: if e.errno == errno.EEXIST: print("%s already exists. Aborting." % arguments.out_dir) sys.exit(1) raise - - for url, schema in REMOTES.items(): - filepath = os.path.join(arguments.out_dir, url) - - try: - os.makedirs(os.path.dirname(filepath)) - except OSError as e: - if e.errno != errno.EEXIST: - raise - - with open(filepath, "w") as out_file: - json.dump(schema, out_file, indent=4, sort_keys=True) - out_file.write("\n") elif arguments.command == "serve": try: - from flask import Flask, jsonify + import flask except ImportError: print(textwrap.dedent(""" The Flask library is required to serve the remote schemas. @@ -237,13 +183,11 @@ """.strip("\n"))) sys.exit(1) - app = Flask(__name__) + app = flask.Flask(__name__) @app.route("/") def serve_path(path): - if path in REMOTES: - return jsonify(REMOTES[path]) - return "Document does not exist.", 404 + return flask.send_from_directory(REMOTES_DIR, path) app.run(port=1234) @@ -251,7 +195,10 @@ parser = argparse.ArgumentParser( description="JSON Schema Test Suite utilities", ) -subparsers = parser.add_subparsers(help="utility commands", dest="command") +subparsers = parser.add_subparsers( + help="utility commands", dest="command", metavar="COMMAND" +) +subparsers.required = True check = subparsers.add_parser("check", help="Sanity check the test suite.") diff -Nru python-jsonschema-3.2.0/json/.github/workflows/ci.yml python-jsonschema-4.6.0/json/.github/workflows/ci.yml --- python-jsonschema-3.2.0/json/.github/workflows/ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/.github/workflows/ci.yml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,25 @@ +name: Test Suite Sanity Checking + +on: + push: + pull_request: + release: + types: [published] + schedule: + # Daily at 6:42 + - cron: '42 6 * * *' + +jobs: + ci: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install tox + run: python -m pip install tox + - name: Run the sanity checks + run: python -m tox diff -Nru python-jsonschema-3.2.0/json/index.js python-jsonschema-4.6.0/json/index.js --- python-jsonschema-3.2.0/json/index.js 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/index.js 2022-06-01 20:26:26.000000000 +0000 @@ -2,12 +2,13 @@ const Ajv = require('ajv'); const jsonSchemaTest = require('json-schema-test'); -const assert = require('assert'); const refs = { 'http://localhost:1234/integer.json': require('./remotes/integer.json'), 'http://localhost:1234/subSchemas.json': require('./remotes/subSchemas.json'), - 'http://localhost:1234/folder/folderInteger.json': require('./remotes/folder/folderInteger.json'), + 'http://localhost:1234/baseUriChange/folderInteger.json': require('./remotes/baseUriChange/folderInteger.json'), + 'http://localhost:1234/baseUriChangeFolder/folderInteger.json': require('./remotes/baseUriChange/folderInteger.json'), + 'http://localhost:1234/baseUriChangeFolderInSubschema/folderInteger.json': require('./remotes/baseUriChange/folderInteger.json'), 'http://localhost:1234/name.json': require('./remotes/name.json'), 'http://localhost:1234/name-defs.json': require('./remotes/name-defs.json') }; diff -Nru python-jsonschema-3.2.0/json/README.md python-jsonschema-4.6.0/json/README.md --- python-jsonschema-3.2.0/json/README.md 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/README.md 2022-06-01 20:26:26.000000000 +0000 @@ -1,5 +1,9 @@ -JSON Schema Test Suite [![Build Status](https://travis-ci.org/json-schema-org/JSON-Schema-Test-Suite.svg?branch=master)](https://travis-ci.org/json-schema-org/JSON-Schema-Test-Suite) -====================== +# JSON Schema Test Suite +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/json-schema-org/.github/blob/main/CODE_OF_CONDUCT.md) +[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Financial Contributors on Open Collective](https://opencollective.com/json-schema/all/badge.svg?label=financial+contributors)](https://opencollective.com/json-schema) + +[![Build Status](https://github.com/json-schema-org/JSON-Schema-Test-Suite/workflows/Test%20Suite%20Sanity%20Checking/badge.svg)](https://github.com/json-schema-org/JSON-Schema-Test-Suite/actions?query=workflow%3A%22Test+Suite+Sanity+Checking%22) This repository contains a set of JSON objects that implementors of JSON Schema validation libraries can use to test their validators. @@ -9,105 +13,127 @@ The conversion of the JSON objects into tests within your test framework of choice is still the job of the validator implementor. -Structure of a Test -------------------- - -If you're going to use this suite, you need to know how tests are laid out. The -tests are contained in the `tests` directory at the root of this repository. +## Structure of a Test -Inside that directory is a subdirectory for each draft or version of the -schema. +The tests in this suite are contained in the `tests` directory at the root of +this repository. Inside that directory is a subdirectory for each draft or +version of the specification. + +Inside each draft directory, there are a number of `.json` files and one or more +special subdirectories. The subdirectories contain `.json` files meant for a +specific testing purpose, and each `.json` file logically groups a set of test +cases together. Often the grouping is by property under test, but not always. -If you look inside the draft directory, there are a number of `.json` files, -which logically group a set of test cases together. Often the grouping is by -property under test, but not always, especially within optional test files -(discussed below). +The subdirectories are described in the next section. Inside each `.json` file is a single array containing objects. It's easiest to illustrate the structure of these with an example: ```json - { - "description": "the description of the test case", - "schema": {"the schema that should" : "be validated against"}, - "tests": [ - { - "description": "a specific test of a valid instance", - "data": "the instance", - "valid": true - }, - { - "description": "another specific test this time, invalid", - "data": 15, - "valid": false - } - ] - } +{ + "description": "The description of the test case", + "schema": { + "description": "The schema against which the data in each test is validated", + "type": "string" + }, + "tests": [ + { + "description": "Test for a valid instance", + "data": "the instance to validate", + "valid": true + }, + { + "description": "Test for an invalid instance", + "data": 15, + "valid": false + } + ] +} ``` -So a description, a schema, and some tests, where tests is an array containing -one or more objects with descriptions, data, and a boolean indicating whether -they should be valid or invalid. - -Coverage --------- - -Drafts 03, 04, 06, and 07 should have full coverage, with drafts 06 and 07 -being considered current and actively supported. Bug fixes will be made as -needed for draft-04 as it is still the most widely used, while draft-03 -is long since deprecated. +In short: a description, a schema under test, and some tests, where each test +in the `tests` array is an objects with a description of the case itself, the +instance under test, and a boolean indicating whether it should be valid +or invalid. + +## Test Subdirectories + +There is currently only one subdirectory that may exist within each draft +directory. This is: + +1. `optional/`: Contains tests that are considered optional. + +## Coverage + +All JSON Schema specification releases should be well covered by this suite, +including drafts 2020-12, 2019-09, 07, 06, 04 and 03. Additional coverage is +always welcome, particularly for bugs encountered in real-world +implementations. + +Drafts 04 and 03 are considered "frozen" in that less effort is put in to +backport new tests to these versions. -If you see anything missing from the current supported drafts, or incorrect -on any draft still accepting bug fixes, please file an issue or submit a PR. +Contributions are very welcome, especially from implementers as they add support +to their own implementations. -Who Uses the Test Suite ------------------------ +If you see anything missing from the current supported drafts, or incorrect on +any draft still accepting bug fixes, please +[file an issue](https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues) +or [submit a PR](https://github.com/json-schema-org/JSON-Schema-Test-Suite). + +## Who Uses the Test Suite This suite is being used by: -### Clojure ### +### Clojure * [jinx](https://github.com/juxt/jinx) * [json-schema](https://github.com/tatut/json-schema) -### Coffeescript ### +### Coffeescript * [jsck](https://github.com/pandastrike/jsck) -### C++ ### +### Common Lisp + +* [json-schema](https://github.com/fisxoj/json-schema) + +### C++ * [Modern C++ JSON schema validator](https://github.com/pboettch/json-schema-validator) -### Dart ### +### Dart -* [json_schema](https://github.com/patefacio/json_schema) +* [json\_schema](https://github.com/patefacio/json_schema) -### Elixir ### +### Elixir -* [ex_json_schema](https://github.com/jonasschmidt/ex_json_schema) +* [ex\_json\_schema](https://github.com/jonasschmidt/ex_json_schema) -### Erlang ### +### Erlang * [jesse](https://github.com/for-GET/jesse) -### Go ### +### Go * [gojsonschema](https://github.com/sigu-399/gojsonschema) * [validate-json](https://github.com/cesanta/validate-json) -### Haskell ### +### Haskell * [aeson-schema](https://github.com/timjb/aeson-schema) * [hjsonschema](https://github.com/seagreen/hjsonschema) -### Java ### +### Java * [json-schema-validator](https://github.com/daveclayton/json-schema-validator) * [everit-org/json-schema](https://github.com/everit-org/json-schema) * [networknt/json-schema-validator](https://github.com/networknt/json-schema-validator) * [Justify](https://github.com/leadpony/justify) +* [Snow](https://github.com/ssilverman/snowy-json) +* [jsonschemafriend](https://github.com/jimblackler/jsonschemafriend) -### JavaScript ### +### JavaScript * [json-schema-benchmark](https://github.com/Muscula/json-schema-benchmark) * [direct-schema](https://github.com/IreneKnapp/direct-schema) @@ -125,7 +151,7 @@ * [ajv](https://github.com/epoberezkin/ajv) * [djv](https://github.com/korzio/djv) -### Node.js ### +### Node.js For node.js developers, the suite is also available as an [npm](https://www.npmjs.com/package/@json-schema-org/tests) package. @@ -134,48 +160,61 @@ repository](https://github.com/json-schema-org/json-schema-test-suite-npm) which also welcomes your contributions! -### .NET ### +### .NET * [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema) * [Manatee.Json](https://github.com/gregsdennis/Manatee.Json) -### PHP ### +### Perl + +* [JSON::Schema::Draft201909](https://github.com/karenetheridge/JSON-Schema-Draft201909) +* [JSON::Schema::Tiny](https://github.com/karenetheridge/JSON-Schema-Tiny) +* [Test::JSON::Schema::Acceptance](https://github.com/karenetheridge/Test-JSON-Schema-Acceptance) +### PHP + +* [opis/json-schema](https://github.com/opis/json-schema) * [json-schema](https://github.com/justinrainbow/json-schema) * [json-guard](https://github.com/thephpleague/json-guard) -### PostgreSQL ### +### PostgreSQL * [postgres-json-schema](https://github.com/gavinwahl/postgres-json-schema) -* [is_jsonb_valid](https://github.com/furstenheim/is_jsonb_valid) +* [is\_jsonb\_valid](https://github.com/furstenheim/is_jsonb_valid) -### Python ### +### Python * [jsonschema](https://github.com/Julian/jsonschema) * [fastjsonschema](https://github.com/seznam/python-fastjsonschema) * [hypothesis-jsonschema](https://github.com/Zac-HD/hypothesis-jsonschema) +* [jschon](https://github.com/marksparkza/jschon) -### Ruby ### +### Ruby * [json-schema](https://github.com/hoxworth/json-schema) -* [json_schemer](https://github.com/davishmcclurg/json_schemer) +* [json\_schemer](https://github.com/davishmcclurg/json_schemer) -### Rust ### +### Rust +* [jsonschema](https://github.com/Stranger6667/jsonschema-rs) * [valico](https://github.com/rustless/valico) -### Swift ### +### Scala + +* [typed-json](https://github.com/frawa/typed-json) + +### Swift * [JSONSchema](https://github.com/kylef/JSONSchema.swift) If you use it as well, please fork and send a pull request adding yourself to the list :). -Contributing ------------- +## Contributing If you see something missing or incorrect, a pull request is most welcome! There are some sanity checks in place for testing the test suite. You can run -them with `bin/jsonschema_suite check && npm test` or `tox && npm test`. They will be run automatically by -[Travis CI](https://travis-ci.org/) as well. +them with `bin/jsonschema_suite check` or `tox`. They will be run automatically +by [GitHub Actions](https://github.com/json-schema-org/JSON-Schema-Test-Suite/actions?query=workflow%3A%22Test+Suite+Sanity+Checking%22) +as well. diff -Nru python-jsonschema-3.2.0/json/remotes/baseUriChange/folderInteger.json python-jsonschema-4.6.0/json/remotes/baseUriChange/folderInteger.json --- python-jsonschema-3.2.0/json/remotes/baseUriChange/folderInteger.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/baseUriChange/folderInteger.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,3 @@ +{ + "type": "integer" +} diff -Nru python-jsonschema-3.2.0/json/remotes/baseUriChangeFolder/folderInteger.json python-jsonschema-4.6.0/json/remotes/baseUriChangeFolder/folderInteger.json --- python-jsonschema-3.2.0/json/remotes/baseUriChangeFolder/folderInteger.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/baseUriChangeFolder/folderInteger.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,3 @@ +{ + "type": "integer" +} diff -Nru python-jsonschema-3.2.0/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json python-jsonschema-4.6.0/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json --- python-jsonschema-3.2.0/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,3 @@ +{ + "type": "integer" +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft2019-09/metaschema-no-validation.json python-jsonschema-4.6.0/json/remotes/draft2019-09/metaschema-no-validation.json --- python-jsonschema-3.2.0/json/remotes/draft2019-09/metaschema-no-validation.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft2019-09/metaschema-no-validation.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/draft2019-09/metaschema-no-validation.json", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/applicator": true, + "https://json-schema.org/draft/2019-09/vocab/core": true + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/2019-09/meta/applicator" }, + { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft2020-12/format-assertion-false.json python-jsonschema-4.6.0/json/remotes/draft2020-12/format-assertion-false.json --- python-jsonschema-3.2.0/json/remotes/draft2020-12/format-assertion-false.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft2020-12/format-assertion-false.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,12 @@ +{ + "$id": "http://localhost:1234/draft2020-12/format-assertion-false.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/core": true, + "https://json-schema.org/draft/2020-12/vocab/format-assertion": false + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/2020-12/schema/meta/core" }, + { "$ref": "https://json-schema.org/draft/2020-12/schema/meta/format-assertion" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft2020-12/format-assertion-true.json python-jsonschema-4.6.0/json/remotes/draft2020-12/format-assertion-true.json --- python-jsonschema-3.2.0/json/remotes/draft2020-12/format-assertion-true.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft2020-12/format-assertion-true.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,12 @@ +{ + "$id": "http://localhost:1234/draft2020-12/format-assertion-true.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/core": true, + "https://json-schema.org/draft/2020-12/vocab/format-assertion": true + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/2020-12/schema/meta/core" }, + { "$ref": "https://json-schema.org/draft/2020-12/schema/meta/format-assertion" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft2020-12/metaschema-no-validation.json python-jsonschema-4.6.0/json/remotes/draft2020-12/metaschema-no-validation.json --- python-jsonschema-3.2.0/json/remotes/draft2020-12/metaschema-no-validation.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft2020-12/metaschema-no-validation.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/draft2020-12/metaschema-no-validation.json", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/applicator": true, + "https://json-schema.org/draft/2020-12/vocab/core": true + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/2020-12/meta/applicator" }, + { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft-next/format-assertion-false.json python-jsonschema-4.6.0/json/remotes/draft-next/format-assertion-false.json --- python-jsonschema-3.2.0/json/remotes/draft-next/format-assertion-false.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft-next/format-assertion-false.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,12 @@ +{ + "$id": "http://localhost:1234/draft-next/format-assertion-false.json", + "$schema": "https://json-schema.org/draft/next/schema", + "$vocabulary": { + "https://json-schema.org/draft/next/vocab/core": true, + "https://json-schema.org/draft/next/vocab/format-assertion": false + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/next/schema/meta/core" }, + { "$ref": "https://json-schema.org/draft/next/schema/meta/format-assertion" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft-next/format-assertion-true.json python-jsonschema-4.6.0/json/remotes/draft-next/format-assertion-true.json --- python-jsonschema-3.2.0/json/remotes/draft-next/format-assertion-true.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft-next/format-assertion-true.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,12 @@ +{ + "$id": "http://localhost:1234/draft-next/format-assertion-true.json", + "$schema": "https://json-schema.org/draft/next/schema", + "$vocabulary": { + "https://json-schema.org/draft/next/vocab/core": true, + "https://json-schema.org/draft/next/vocab/format-assertion": true + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/next/schema/meta/core" }, + { "$ref": "https://json-schema.org/draft/next/schema/meta/format-assertion" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/draft-next/metaschema-no-validation.json python-jsonschema-4.6.0/json/remotes/draft-next/metaschema-no-validation.json --- python-jsonschema-3.2.0/json/remotes/draft-next/metaschema-no-validation.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/draft-next/metaschema-no-validation.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/draft-next/metaschema-no-validation.json", + "$vocabulary": { + "https://json-schema.org/draft/next/vocab/applicator": true, + "https://json-schema.org/draft/next/vocab/core": true + }, + "allOf": [ + { "$ref": "https://json-schema.org/draft/next/meta/applicator" }, + { "$ref": "https://json-schema.org/draft/next/meta/core" } + ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/extendible-dynamic-ref.json python-jsonschema-4.6.0/json/remotes/extendible-dynamic-ref.json --- python-jsonschema-3.2.0/json/remotes/extendible-dynamic-ref.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/extendible-dynamic-ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,20 @@ +{ + "description": "extendible array", + "$id": "http://localhost:1234/extendible-dynamic-ref.json", + "type": "object", + "properties": { + "elements": { + "type": "array", + "items": { + "$dynamicRef": "#elements" + } + } + }, + "required": ["elements"], + "additionalProperties": false, + "$defs": { + "elements": { + "$dynamicAnchor": "elements" + } + } +} diff -Nru python-jsonschema-3.2.0/json/remotes/folder/folderInteger.json python-jsonschema-4.6.0/json/remotes/folder/folderInteger.json --- python-jsonschema-3.2.0/json/remotes/folder/folderInteger.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/folder/folderInteger.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ - "type": "integer" -} diff -Nru python-jsonschema-3.2.0/json/remotes/ref-and-definitions.json python-jsonschema-4.6.0/json/remotes/ref-and-definitions.json --- python-jsonschema-3.2.0/json/remotes/ref-and-definitions.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/ref-and-definitions.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/ref-and-definitions.json", + "definitions": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] +} diff -Nru python-jsonschema-3.2.0/json/remotes/ref-and-defs.json python-jsonschema-4.6.0/json/remotes/ref-and-defs.json --- python-jsonschema-3.2.0/json/remotes/ref-and-defs.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/ref-and-defs.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/ref-and-defs.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" +} diff -Nru python-jsonschema-3.2.0/json/remotes/subSchemas-defs.json python-jsonschema-4.6.0/json/remotes/subSchemas-defs.json --- python-jsonschema-3.2.0/json/remotes/subSchemas-defs.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/subSchemas-defs.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } + } +} diff -Nru python-jsonschema-3.2.0/json/remotes/tree.json python-jsonschema-4.6.0/json/remotes/tree.json --- python-jsonschema-3.2.0/json/remotes/tree.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/remotes/tree.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,16 @@ +{ + "description": "tree schema, extensible", + "$id": "http://localhost:1234/tree.json", + "$dynamicAnchor": "node", + + "type": "object", + "properties": { + "data": true, + "children": { + "type": "array", + "items": { + "$dynamicRef": "#node" + } + } + } +} diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/additionalItems.json python-jsonschema-4.6.0/json/tests/draft2019-09/additionalItems.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/additionalItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/additionalItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -19,7 +19,7 @@ ] }, { - "description": "items is schema, no additionalItems", + "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false @@ -33,14 +33,24 @@ ] }, { - "description": "array of items with no additionalItems", + "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { - "description": "fewer number of items present", + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, @@ -83,5 +93,57 @@ "valid": true } ] + }, + { + "description": "additionalItems should not look in applicators, valid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" } ] } + ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, null ], + "valid": true + } + ] + }, + { + "description": "additionalItems should not look in applicators, invalid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" }, { "type": "string" } ] } + ], + "items": [ {"type": "integer" } ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, "hello" ], + "valid": false + } + ] + }, + { + "description": "items validation adjusts the starting index for additionalItems", + "schema": { + "items": [ { "type": "string" } ], + "additionalItems": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft2019-09/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/additionalProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -124,7 +124,7 @@ }, "tests": [ { - "description": "properties defined in allOf are not allowed", + "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/allOf.json python-jsonschema-4.6.0/json/tests/draft2019-09/allOf.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/allOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -214,5 +214,81 @@ "valid": false } ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/anchor.json python-jsonschema-4.6.0/json/tests/draft2019-09/anchor.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/anchor.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/anchor.json 2022-06-01 20:26:26.000000000 +0000 @@ -2,9 +2,7 @@ { "description": "Location-independent identifier", "schema": { - "allOf": [{ - "$ref": "#foo" - }], + "$ref": "#foo", "$defs": { "A": { "$anchor": "foo", @@ -28,9 +26,7 @@ { "description": "Location-independent identifier with absolute URI", "schema": { - "allOf": [{ - "$ref": "http://localhost:1234/bar#foo" - }], + "$ref": "http://localhost:1234/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/bar", @@ -56,9 +52,7 @@ "description": "Location-independent identifier with base URI change in subschema", "schema": { "$id": "http://localhost:1234/root", - "allOf": [{ - "$ref": "http://localhost:1234/nested.json#foo" - }], + "$ref": "http://localhost:1234/nested.json#foo", "$defs": { "A": { "$id": "nested.json", @@ -83,5 +77,97 @@ "valid": false } ] + }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, + { + "description": "same $anchor with different base uri", + "schema": { + "$id": "http://localhost:1234/foobar", + "$defs": { + "A": { + "$id": "child1", + "allOf": [ + { + "$id": "child2", + "$anchor": "my_anchor", + "type": "number" + }, + { + "$anchor": "my_anchor", + "type": "string" + } + ] + } + }, + "$ref": "child1#my_anchor" + }, + "tests": [ + { + "description": "$ref should resolve to /$defs/A/allOf/1", + "data": "a", + "valid": true + }, + { + "description": "$ref should not resolve to /$defs/A/allOf/0", + "data": 1, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/const.json python-jsonschema-4.6.0/json/tests/draft2019-09/const.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/const.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/const.json 2022-06-01 20:26:26.000000000 +0000 @@ -126,7 +126,91 @@ ] }, { - "description": "const with 0 does not match false", + "description": "const with [false] does not match [0]", + "schema": {"const": [false]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, + { + "description": "const with [true] does not match [1]", + "schema": {"const": [true]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, + { + "description": "const with {\"a\": false} does not match {\"a\": 0}", + "schema": {"const": {"a": false}}, + "tests": [ + { + "description": "{\"a\": false} is valid", + "data": {"a": false}, + "valid": true + }, + { + "description": "{\"a\": 0} is invalid", + "data": {"a": 0}, + "valid": false + }, + { + "description": "{\"a\": 0.0} is invalid", + "data": {"a": 0.0}, + "valid": false + } + ] + }, + { + "description": "const with {\"a\": true} does not match {\"a\": 1}", + "schema": {"const": {"a": true}}, + "tests": [ + { + "description": "{\"a\": true} is valid", + "data": {"a": true}, + "valid": true + }, + { + "description": "{\"a\": 1} is invalid", + "data": {"a": 1}, + "valid": false + }, + { + "description": "{\"a\": 1.0} is invalid", + "data": {"a": 1.0}, + "valid": false + } + ] + }, + { + "description": "const with 0 does not match other zero-like types", "schema": {"const": 0}, "tests": [ { @@ -143,6 +227,21 @@ "description": "float zero is valid", "data": 0.0, "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "empty string is invalid", + "data": "", + "valid": false } ] }, @@ -166,5 +265,78 @@ "valid": true } ] + }, + { + "description": "const with -2.0 matches integer and float types", + "schema": {"const": -2.0}, + "tests": [ + { + "description": "integer -2 is valid", + "data": -2, + "valid": true + }, + { + "description": "integer 2 is invalid", + "data": 2, + "valid": false + }, + { + "description": "float -2.0 is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float 2.0 is invalid", + "data": 2.0, + "valid": false + }, + { + "description": "float -2.00001 is invalid", + "data": -2.00001, + "valid": false + } + ] + }, + { + "description": "float and integers are equal up to 64-bit representation limits", + "schema": {"const": 9007199254740992}, + "tests": [ + { + "description": "integer is valid", + "data": 9007199254740992, + "valid": true + }, + { + "description": "integer minus one is invalid", + "data": 9007199254740991, + "valid": false + }, + { + "description": "float is valid", + "data": 9007199254740992.0, + "valid": true + }, + { + "description": "float minus one is invalid", + "data": 9007199254740991.0, + "valid": false + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "const": "hello\u0000there" }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/contains.json python-jsonschema-4.6.0/json/tests/draft2019-09/contains.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/contains.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/contains.json 2022-06-01 20:26:26.000000000 +0000 @@ -89,6 +89,61 @@ "description": "empty array is invalid", "data": [], "valid": false + }, + { + "description": "non-arrays are valid", + "data": "contains does not apply to strings", + "valid": true + } + ] + }, + { + "description": "items + contains", + "schema": { + "items": { "multipleOf": 2 }, + "contains": { "multipleOf": 3 } + }, + "tests": [ + { + "description": "matches items, does not match contains", + "data": [ 2, 4, 8 ], + "valid": false + }, + { + "description": "does not match items, matches contains", + "data": [ 3, 6, 9 ], + "valid": false + }, + { + "description": "matches both items and contains", + "data": [ 6, 12 ], + "valid": true + }, + { + "description": "matches neither items nor contains", + "data": [ 1, 5 ], + "valid": false + } + ] + }, + { + "description": "contains with false if subschema", + "schema": { + "contains": { + "if": false, + "else": true + } + }, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/content.json python-jsonschema-4.6.0/json/tests/draft2019-09/content.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/content.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/content.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,127 @@ +[ + { + "description": "validation of string-encoded content based on media type", + "schema": { + "contentMediaType": "application/json" + }, + "tests": [ + { + "description": "a valid JSON document", + "data": "{\"foo\": \"bar\"}", + "valid": true + }, + { + "description": "an invalid JSON document; validates true", + "data": "{:}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary string-encoding", + "schema": { + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64 string", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "an invalid base64 string (% is not a valid character); validates true", + "data": "eyJmb28iOi%iYmFyIn0K", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents with schema", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64", + "contentSchema": { "required": ["foo"], "properties": { "foo": { "type": "string" } } } + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "another valid base64-encoded JSON document", + "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", + "valid": true + }, + { + "description": "an invalid base64-encoded JSON document; validates true", + "data": "eyJib28iOiAyMH0=", + "valid": true + }, + { + "description": "an empty object as a base64-encoded JSON document; validates true", + "data": "e30=", + "valid": true + }, + { + "description": "an empty array as a base64-encoded JSON document", + "data": "W10=", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/default.json python-jsonschema-4.6.0/json/tests/draft2019-09/default.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/default.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,5 +45,35 @@ "valid": true } ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/defs.json python-jsonschema-4.6.0/json/tests/draft2019-09/defs.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/defs.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/defs.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,19 +1,13 @@ [ { - "description": "valid definition", + "description": "validate definition against metaschema", "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, "tests": [ { "description": "valid definition schema", "data": {"$defs": {"foo": {"type": "integer"}}}, "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, - "tests": [ + }, { "description": "invalid definition schema", "data": {"$defs": {"foo": {"type": 1}}}, diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/dependencies.json python-jsonschema-4.6.0/json/tests/draft2019-09/dependencies.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/dependencies.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/dependencies.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -[ - { - "description": "dependencies", - "schema": { - "dependencies": {"bar": ["foo"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependant", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "with dependency", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "ignores arrays", - "data": ["bar"], - "valid": true - }, - { - "description": "ignores strings", - "data": "foobar", - "valid": true - }, - { - "description": "ignores other non-objects", - "data": 12, - "valid": true - } - ] - }, - { - "description": "dependencies with empty array", - "schema": { - "dependencies": {"bar": []} - }, - "tests": [ - { - "description": "empty object", - "data": {}, - "valid": true - }, - { - "description": "object with one property", - "data": {"bar": 2}, - "valid": true - } - ] - }, - { - "description": "multiple dependencies", - "schema": { - "dependencies": {"quux": ["foo", "bar"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependants", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "with dependencies", - "data": {"foo": 1, "bar": 2, "quux": 3}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"foo": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing other dependency", - "data": {"bar": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing both dependencies", - "data": {"quux": 1}, - "valid": false - } - ] - }, - { - "description": "multiple dependencies subschema", - "schema": { - "dependencies": { - "bar": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"type": "integer"} - } - } - } - }, - "tests": [ - { - "description": "valid", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "no dependency", - "data": {"foo": "quux"}, - "valid": true - }, - { - "description": "wrong type", - "data": {"foo": "quux", "bar": 2}, - "valid": false - }, - { - "description": "wrong type other", - "data": {"foo": 2, "bar": "quux"}, - "valid": false - }, - { - "description": "wrong type both", - "data": {"foo": "quux", "bar": "quux"}, - "valid": false - } - ] - }, - { - "description": "dependencies with boolean subschemas", - "schema": { - "dependencies": { - "foo": true, - "bar": false - } - }, - "tests": [ - { - "description": "object with property having schema true is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with property having schema false is invalid", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "object with both properties is invalid", - "data": {"foo": 1, "bar": 2}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] - }, - { - "description": "empty array of dependencies", - "schema": { - "dependencies": { - "foo": [] - } - }, - "tests": [ - { - "description": "object with property is valid", - "data": { "foo": 1 }, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "non-object is valid", - "data": 1, - "valid": true - } - ] - }, - { - "description": "dependencies with escaped characters", - "schema": { - "dependencies": { - "foo\nbar": ["foo\rbar"], - "foo\tbar": { - "minProperties": 4 - }, - "foo'bar": {"required": ["foo\"bar"]}, - "foo\"bar": ["foo'bar"] - } - }, - "tests": [ - { - "description": "valid object 1", - "data": { - "foo\nbar": 1, - "foo\rbar": 2 - }, - "valid": true - }, - { - "description": "valid object 2", - "data": { - "foo\tbar": 1, - "a": 2, - "b": 3, - "c": 4 - }, - "valid": true - }, - { - "description": "valid object 3", - "data": { - "foo'bar": 1, - "foo\"bar": 2 - }, - "valid": true - }, - { - "description": "invalid object 1", - "data": { - "foo\nbar": 1, - "foo": 2 - }, - "valid": false - }, - { - "description": "invalid object 2", - "data": { - "foo\tbar": 1, - "a": 2 - }, - "valid": false - }, - { - "description": "invalid object 3", - "data": { - "foo'bar": 1 - }, - "valid": false - }, - { - "description": "invalid object 4", - "data": { - "foo\"bar": 2 - }, - "valid": false - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/dependentRequired.json python-jsonschema-4.6.0/json/tests/draft2019-09/dependentRequired.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/dependentRequired.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/dependentRequired.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,142 @@ +[ + { + "description": "single dependency", + "schema": {"dependentRequired": {"bar": ["foo"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "empty dependents", + "schema": {"dependentRequired": {"bar": []}}, + "tests": [ + { + "description": "empty object", + "data": {}, + "valid": true + }, + { + "description": "object with one property", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "non-object is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "multiple dependents required", + "schema": {"dependentRequired": {"quux": ["foo", "bar"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentRequired": { + "foo\nbar": ["foo\rbar"], + "foo\"bar": ["foo'bar"] + } + }, + "tests": [ + { + "description": "CRLF", + "data": { + "foo\nbar": 1, + "foo\rbar": 2 + }, + "valid": true + }, + { + "description": "quoted quotes", + "data": { + "foo'bar": 1, + "foo\"bar": 2 + }, + "valid": true + }, + { + "description": "CRLF missing dependent", + "data": { + "foo\nbar": 1, + "foo": 2 + }, + "valid": false + }, + { + "description": "quoted quotes missing dependent", + "data": { + "foo\"bar": 2 + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/dependentSchemas.json python-jsonschema-4.6.0/json/tests/draft2019-09/dependentSchemas.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/dependentSchemas.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/dependentSchemas.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,129 @@ +[ + { + "description": "single dependency", + "schema": { + "dependentSchemas": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "boolean subschemas", + "schema": { + "dependentSchemas": { + "foo": true, + "bar": false + } + }, + "tests": [ + { + "description": "object with property having schema true is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property having schema false is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "object with both properties is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentSchemas": { + "foo\tbar": {"minProperties": 4}, + "foo'bar": {"required": ["foo\"bar"]} + } + }, + "tests": [ + { + "description": "quoted tab", + "data": { + "foo\tbar": 1, + "a": 2, + "b": 3, + "c": 4 + }, + "valid": true + }, + { + "description": "quoted quote", + "data": { + "foo'bar": {"foo\"bar": 1} + }, + "valid": false + }, + { + "description": "quoted tab invalid under dependent schema", + "data": { + "foo\tbar": 1, + "a": 2 + }, + "valid": false + }, + { + "description": "quoted quote invalid under dependent schema", + "data": {"foo'bar": 1}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/enum.json python-jsonschema-4.6.0/json/tests/draft2019-09/enum.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/enum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -33,6 +33,37 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false } ] }, @@ -53,6 +84,16 @@ "valid": true }, { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true @@ -175,5 +216,21 @@ "valid": true } ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/format.json python-jsonschema-4.6.0/json/tests/draft2019-09/format.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,611 +1,683 @@ [ { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "description": "email format", + "schema": { "format": "email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IDN e-mail addresses", - "schema": {"format": "idn-email"}, + "description": "idn-email format", + "schema": { "format": "idn-email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of regexes", - "schema": {"format": "regex"}, + "description": "regex format", + "schema": { "format": "regex" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "description": "ipv4 format", + "schema": { "format": "ipv4" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "description": "ipv6 format", + "schema": { "format": "ipv6" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IDN hostnames", - "schema": {"format": "idn-hostname"}, + "description": "idn-hostname format", + "schema": { "format": "idn-hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of hostnames", - "schema": {"format": "hostname"}, + "description": "hostname format", + "schema": { "format": "hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date strings", - "schema": {"format": "date"}, + "description": "date format", + "schema": { "format": "date" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "description": "date-time format", + "schema": { "format": "date-time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of time strings", - "schema": {"format": "time"}, + "description": "time format", + "schema": { "format": "time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of JSON pointers", - "schema": {"format": "json-pointer"}, + "description": "json-pointer format", + "schema": { "format": "json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of relative JSON pointers", - "schema": {"format": "relative-json-pointer"}, + "description": "relative-json-pointer format", + "schema": { "format": "relative-json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IRIs", - "schema": {"format": "iri"}, + "description": "iri format", + "schema": { "format": "iri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IRI references", - "schema": {"format": "iri-reference"}, + "description": "iri-reference format", + "schema": { "format": "iri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URIs", - "schema": {"format": "uri"}, + "description": "uri format", + "schema": { "format": "uri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI references", - "schema": {"format": "uri-reference"}, + "description": "uri-reference format", + "schema": { "format": "uri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI templates", - "schema": {"format": "uri-template"}, + "description": "uri-template format", + "schema": { "format": "uri-template" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uuid format", + "schema": { "format": "uuid" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "duration format", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", "data": null, "valid": true } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/id.json python-jsonschema-4.6.0/json/tests/draft2019-09/id.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,256 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/if-then-else.json python-jsonschema-4.6.0/json/tests/draft2019-09/if-then-else.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/if-then-else.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/if-then-else.json 2022-06-01 20:26:26.000000000 +0000 @@ -184,5 +184,75 @@ "valid": true } ] + }, + { + "description": "if with boolean schema true", + "schema": { + "if": true, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema true in if always chooses the then path (valid)", + "data": "then", + "valid": true + }, + { + "description": "boolean schema true in if always chooses the then path (invalid)", + "data": "else", + "valid": false + } + ] + }, + { + "description": "if with boolean schema false", + "schema": { + "if": false, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema false in if always chooses the else path (invalid)", + "data": "then", + "valid": false + }, + { + "description": "boolean schema false in if always chooses the else path (valid)", + "data": "else", + "valid": true + } + ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft2019-09/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "$defs": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/$defs/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/$defs/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/maxContains.json python-jsonschema-4.6.0/json/tests/draft2019-09/maxContains.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/maxContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/maxContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,79 @@ +[ + { + "description": "maxContains without contains is ignored", + "schema": { + "maxContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "two items still valid against lone maxContains", + "data": [ 1, 2 ], + "valid": true + } + ] + }, + { + "description": "maxContains with contains", + "schema": { + "contains": {"const": 1}, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, valid maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "all elements match, invalid maxContains", + "data": [ 1, 1 ], + "valid": false + }, + { + "description": "some elements match, valid maxContains", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "some elements match, invalid maxContains", + "data": [ 1, 2, 1 ], + "valid": false + } + ] + }, + { + "description": "minContains < maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 1, + "maxContains": 3 + }, + "tests": [ + { + "description": "actual < minContains < maxContains", + "data": [ ], + "valid": false + }, + { + "description": "minContains < actual < maxContains", + "data": [ 1, 1 ], + "valid": true + }, + { + "description": "minContains < maxContains < actual", + "data": [ 1, 1, 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/maximum.json python-jsonschema-4.6.0/json/tests/draft2019-09/maximum.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/maximum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -24,5 +24,31 @@ "valid": true } ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/maxProperties.json python-jsonschema-4.6.0/json/tests/draft2019-09/maxProperties.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/maxProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -34,5 +34,21 @@ "valid": true } ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/minContains.json python-jsonschema-4.6.0/json/tests/draft2019-09/minContains.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/minContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/minContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,197 @@ +[ + { + "description": "minContains without contains is ignored", + "schema": { + "minContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone minContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "zero items still valid against lone minContains", + "data": [], + "valid": true + } + ] + }, + { + "description": "minContains=1 with contains", + "schema": { + "contains": {"const": 1}, + "minContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "no elements match", + "data": [ 2 ], + "valid": false + }, + { + "description": "single element matches, valid minContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "all elements match, valid minContains", + "data": [ 1, 1 ], + "valid": true + } + ] + }, + { + "description": "minContains=2 with contains", + "schema": { + "contains": {"const": 1}, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "some elements match, invalid minContains", + "data": [ 1, 2 ], + "valid": false + }, + { + "description": "all elements match, valid minContains (exactly as needed)", + "data": [ 1, 1 ], + "valid": true + }, + { + "description": "all elements match, valid minContains (more than needed)", + "data": [ 1, 1, 1 ], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [ 1, 2, 1 ], + "valid": true + } + ] + }, + { + "description": "maxContains = minContains", + "schema": { + "contains": {"const": 1}, + "maxContains": 2, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "all elements match, invalid maxContains", + "data": [ 1, 1, 1 ], + "valid": false + }, + { + "description": "all elements match, valid maxContains and minContains", + "data": [ 1, 1 ], + "valid": true + } + ] + }, + { + "description": "maxContains < minContains", + "schema": { + "contains": {"const": 1}, + "maxContains": 1, + "minContains": 3 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "invalid maxContains", + "data": [ 1, 1, 1 ], + "valid": false + }, + { + "description": "invalid maxContains and minContains", + "data": [ 1, 1 ], + "valid": false + } + ] + }, + { + "description": "minContains = 0 with no maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 0 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "minContains = 0 makes contains always pass", + "data": [ 2 ], + "valid": true + } + ] + }, + { + "description": "minContains = 0 with maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 0, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "not more than maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "too many", + "data": [ 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/minimum.json python-jsonschema-4.6.0/json/tests/draft2019-09/minimum.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/minimum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,7 +45,17 @@ "valid": true }, { - "description": "below the minimum is invalid", + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", "data": -3, "valid": false }, diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/multipleOf.json python-jsonschema-4.6.0/json/tests/draft2019-09/multipleOf.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/multipleOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/oneOf.json python-jsonschema-4.6.0/json/tests/draft2019-09/oneOf.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/oneOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -202,5 +202,73 @@ "valid": false } ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": true, + "baz": true + }, + "required": ["bar"] + }, + { + "properties": { + "foo": true + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/bignum.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/bignum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,30 +1,13 @@ [ { "description": "integer", - "schema": {"type": "integer"}, + "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ + }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, @@ -34,9 +17,14 @@ }, { "description": "number", - "schema": {"type": "number"}, + "schema": { "type": "number" }, "tests": [ { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true @@ -45,7 +33,7 @@ }, { "description": "string", - "schema": {"type": "string"}, + "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", @@ -56,7 +44,7 @@ }, { "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, + "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", @@ -80,7 +68,7 @@ }, { "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, + "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/content.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/content.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/content.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/content.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -[ - { - "description": "validation of string-encoded content based on media type", - "schema": { - "contentMediaType": "application/json" - }, - "tests": [ - { - "description": "a valid JSON document", - "data": "{\"foo\": \"bar\"}", - "valid": true - }, - { - "description": "an invalid JSON document", - "data": "{:}", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - }, - { - "description": "validation of binary string-encoding", - "schema": { - "contentEncoding": "base64" - }, - "tests": [ - { - "description": "a valid base64 string", - "data": "eyJmb28iOiAiYmFyIn0K", - "valid": true - }, - { - "description": "an invalid base64 string (% is not a valid character)", - "data": "eyJmb28iOi%iYmFyIn0K", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - }, - { - "description": "validation of binary-encoded media type documents", - "schema": { - "contentMediaType": "application/json", - "contentEncoding": "base64" - }, - "tests": [ - { - "description": "a valid base64-encoded JSON document", - "data": "eyJmb28iOiAiYmFyIn0K", - "valid": true - }, - { - "description": "a validly-encoded invalid JSON document", - "data": "ezp9Cg==", - "valid": false - }, - { - "description": "an invalid base64 string that is valid JSON", - "data": "{}", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/ecmascript-regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", @@ -19,7 +8,7 @@ "tests": [ { "description": "matches in Python, but should not in jsonschema", - "data": "abc\n", + "data": "abc\\n", "valid": false }, { @@ -30,20 +19,20 @@ ] }, { - "description": "ECMA 262 regex converts \\a to ascii BEL", + "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", - "pattern": "^\\a$" + "pattern": "^\\t$" }, "tests": [ { "description": "does not match", - "data": "\\a", + "data": "\\t", "valid": false }, { "description": "matches", - "data": "\u0007", + "data": "\u0009", "valid": true } ] @@ -154,7 +143,7 @@ ] }, { - "description": "ECMA 262 \\w matches everything but ascii letters", + "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" @@ -173,7 +162,7 @@ ] }, { - "description": "ECMA 262 \\s matches ascii whitespace only", + "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" @@ -185,14 +174,59 @@ "valid": true }, { - "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", "valid": false } ] }, { - "description": "ECMA 262 \\S matches everything but ascii whitespace", + "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" @@ -204,8 +238,313 @@ "valid": false }, { - "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/date.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/date.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/date.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/date.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,180 @@ [ { "description": "validation of date strings", - "schema": {"format": "date"}, + "schema": { "format": "date" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { - "description": "an invalid date-time string", + "description": "a valid date string with 31 days in January", + "data": "2020-01-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in January", + "data": "2020-01-32", + "valid": false + }, + { + "description": "a valid date string with 28 days in February (normal)", + "data": "2021-02-28", + "valid": true + }, + { + "description": "a invalid date string with 29 days in February (normal)", + "data": "2021-02-29", + "valid": false + }, + { + "description": "a valid date string with 29 days in February (leap)", + "data": "2020-02-29", + "valid": true + }, + { + "description": "a invalid date string with 30 days in February (leap)", + "data": "2020-02-30", + "valid": false + }, + { + "description": "a valid date string with 31 days in March", + "data": "2020-03-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in March", + "data": "2020-03-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in April", + "data": "2020-04-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in April", + "data": "2020-04-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in May", + "data": "2020-05-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in May", + "data": "2020-05-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in June", + "data": "2020-06-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in June", + "data": "2020-06-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in July", + "data": "2020-07-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in July", + "data": "2020-07-32", + "valid": false + }, + { + "description": "a valid date string with 31 days in August", + "data": "2020-08-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in August", + "data": "2020-08-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in September", + "data": "2020-09-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in September", + "data": "2020-09-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in October", + "data": "2020-10-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in October", + "data": "2020-10-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in November", + "data": "2020-11-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in November", + "data": "2020-11-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in December", + "data": "2020-12-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in December", + "data": "2020-12-32", + "valid": false + }, + { + "description": "a invalid date string with invalid month", + "data": "2020-13-01", + "valid": false + }, + { + "description": "an invalid date string", "data": "06/19/1963", "valid": false }, @@ -17,6 +182,41 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false + }, + { + "description": "non-padded month dates are not valid", + "data": "1998-1-20", + "valid": false + }, + { + "description": "non-padded day dates are not valid", + "data": "1998-01-1", + "valid": false + }, + { + "description": "invalid month", + "data": "1998-13-01", + "valid": false + }, + { + "description": "invalid month-day combination", + "data": "1998-04-31", + "valid": false + }, + { + "description": "2021 is not a leap year", + "data": "2021-02-29", + "valid": false + }, + { + "description": "2020 is a leap year", + "data": "2020-02-29", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1963-06-1৪", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/date-time.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "schema": { "format": "date-time" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true @@ -24,13 +54,43 @@ "valid": true }, { - "description": "a invalid day in date-time string", - "data": "1990-02-31T15:59:60.123-08:00", + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", - "data": "1990-12-31T15:59:60-24:00", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { @@ -47,6 +107,26 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/duration.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/duration.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/duration.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/duration.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,128 @@ +[ + { + "description": "validation of duration strings", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid duration string", + "data": "P4DT12H30M5S", + "valid": true + }, + { + "description": "an invalid duration string", + "data": "PT1D", + "valid": false + }, + { + "description": "no elements present", + "data": "P", + "valid": false + }, + { + "description": "no time elements present", + "data": "P1YT", + "valid": false + }, + { + "description": "no date or time elements present", + "data": "PT", + "valid": false + }, + { + "description": "elements out of order", + "data": "P2D1Y", + "valid": false + }, + { + "description": "missing time separator", + "data": "P1D2H", + "valid": false + }, + { + "description": "time element in the date position", + "data": "P2S", + "valid": false + }, + { + "description": "four years duration", + "data": "P4Y", + "valid": true + }, + { + "description": "zero time, in seconds", + "data": "PT0S", + "valid": true + }, + { + "description": "zero time, in days", + "data": "P0D", + "valid": true + }, + { + "description": "one month duration", + "data": "P1M", + "valid": true + }, + { + "description": "one minute duration", + "data": "PT1M", + "valid": true + }, + { + "description": "one and a half days, in hours", + "data": "PT36H", + "valid": true + }, + { + "description": "one and a half days, in days and hours", + "data": "P1DT12H", + "valid": true + }, + { + "description": "two weeks", + "data": "P2W", + "valid": true + }, + { + "description": "weeks cannot be combined with other units", + "data": "P1Y2W", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "P২Y", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/email.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "schema": { "format": "email" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true @@ -12,6 +42,41 @@ "description": "an invalid e-mail address", "data": "2962", "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/hostname.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of host names", - "schema": {"format": "hostname"}, + "schema": { "format": "hostname" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid host name", "data": "www.example.com", "valid": true @@ -27,6 +57,41 @@ "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/idn-email.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/idn-email.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/idn-email.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/idn-email.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of an internationalized e-mail addresses", - "schema": {"format": "idn-email"}, + "schema": { "format": "idn-email" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true @@ -12,6 +42,16 @@ "description": "an invalid idn e-mail address", "data": "2962", "valid": false + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/idn-hostname.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/idn-hostname.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/idn-hostname.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/idn-hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of internationalized host names", - "schema": {"format": "idn-hostname"}, + "schema": { "format": "idn-hostname" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true @@ -22,6 +52,252 @@ "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false + }, + { + "description": "invalid label, correct Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", + "data": "-> $1.00 <--", + "valid": false + }, + { + "description": "valid Chinese Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", + "data": "xn--ihqwcrb4cv8a8dqg056pqjye", + "valid": true + }, + { + "description": "invalid Punycode", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "xn--X", + "valid": false + }, + { + "description": "U-label contains \"--\" in the 3rd and 4th position", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "XN--aa---o47jg78q", + "valid": false + }, + { + "description": "U-label starts with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello", + "valid": false + }, + { + "description": "U-label ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "hello-", + "valid": false + }, + { + "description": "U-label starts and ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello-", + "valid": false + }, + { + "description": "Begins with a Spacing Combining Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0903hello", + "valid": false + }, + { + "description": "Begins with a Nonspacing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0300hello", + "valid": false + }, + { + "description": "Begins with an Enclosing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0488hello", + "valid": false + }, + { + "description": "Exceptions that are PVALID, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u00df\u03c2\u0f0b\u3007", + "valid": true + }, + { + "description": "Exceptions that are PVALID, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u06fd\u06fe", + "valid": true + }, + { + "description": "Exceptions that are DISALLOWED, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u0640\u07fa", + "valid": false + }, + { + "description": "Exceptions that are DISALLOWED, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", + "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", + "valid": false + }, + { + "description": "MIDDLE DOT with no preceding 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "a\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing preceding", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with no following 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7a", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing following", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7", + "valid": false + }, + { + "description": "MIDDLE DOT with surrounding 'l's", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7l", + "valid": true + }, + { + "description": "Greek KERAIA not followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375S", + "valid": false + }, + { + "description": "Greek KERAIA not followed by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375", + "valid": false + }, + { + "description": "Greek KERAIA followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375\u03b2", + "valid": true + }, + { + "description": "Hebrew GERESH not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "A\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05d0\u05f3\u05d1", + "valid": true + }, + { + "description": "Hebrew GERSHAYIM not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "A\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05d0\u05f4\u05d1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "def\u30fbabc", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with no other characters", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with Hiragana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u3041", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Katakana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u30a1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u4e08", + "valid": true + }, + { + "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0660\u06f0", + "valid": false + }, + { + "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0628\u0660\u0628", + "valid": true + }, + { + "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", + "data": "\u06f00", + "valid": true + }, + { + "description": "ZERO WIDTH JOINER not preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u094d\u200d\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", + "data": "\u0915\u094d\u200c\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", + "data": "\u0628\u064a\u200c\u0628\u064a", + "valid": true } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/ipv4.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "schema": { "format": "ipv4" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IP address", "data": "192.168.0.1", "valid": true @@ -27,6 +57,27 @@ "description": "an IP address as an integer", "data": "0x7f000001", "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/ipv6.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "schema": { "format": "ipv6" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IPv6 address", "data": "::1", "valid": true @@ -14,6 +44,16 @@ "valid": false }, { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false @@ -22,6 +62,146 @@ "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/iri.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/iri.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/iri.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/iri.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,45 @@ [ { "description": "validation of IRIs", - "schema": {"format": "iri"}, + "schema": { "format": "iri" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { - "description": "a valid IRI with anchor tag and parantheses", + "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/iri-reference.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/iri-reference.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/iri-reference.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/iri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IRI References", - "schema": {"format": "iri-reference"}, + "schema": { "format": "iri-reference" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/json-pointer.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/json-pointer.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of JSON-pointers (JSON String Representation)", - "schema": {"format": "json-pointer"}, + "schema": { "format": "json-pointer" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/regex.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/regex.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of regular expressions", - "schema": {"format": "regex"}, + "schema": { "format": "regex" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/relative-json-pointer.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/relative-json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/relative-json-pointer.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/relative-json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,45 @@ [ { "description": "validation of Relative JSON Pointers (RJP)", - "schema": {"format": "relative-json-pointer"}, + "schema": { "format": "relative-json-pointer" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid upwards RJP", "data": "1", "valid": true }, { - "description": "a valid downwards RJP", + "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, @@ -27,6 +57,26 @@ "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false + }, + { + "description": "negative prefix", + "data": "-1/foo/bar", + "valid": false + }, + { + "description": "## is not a valid json-pointer", + "data": "0##", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus json-pointer", + "data": "01/a", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus octothorpe", + "data": "01#", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/time.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/time.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/time.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/time.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,180 @@ [ { "description": "validation of time strings", - "schema": {"format": "time"}, + "schema": { "format": "time" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid time string", + "data": "08:30:06Z", + "valid": true + }, + { + "description": "a valid time string with leap second, Zulu", + "data": "23:59:60Z", + "valid": true + }, + { + "description": "invalid leap second, Zulu (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "invalid leap second, Zulu (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "valid leap second, zero time-offset", + "data": "23:59:60+00:00", + "valid": true + }, + { + "description": "invalid leap second, zero time-offset (wrong hour)", + "data": "22:59:60+00:00", + "valid": false + }, + { + "description": "invalid leap second, zero time-offset (wrong minute)", + "data": "23:58:60+00:00", + "valid": false + }, + { + "description": "valid leap second, positive time-offset", + "data": "01:29:60+01:30", + "valid": true + }, + { + "description": "valid leap second, large positive time-offset", + "data": "23:29:60+23:30", + "valid": true + }, + { + "description": "invalid leap second, positive time-offset (wrong hour)", + "data": "23:59:60+01:00", + "valid": false + }, + { + "description": "invalid leap second, positive time-offset (wrong minute)", + "data": "23:59:60+00:30", + "valid": false + }, + { + "description": "valid leap second, negative time-offset", + "data": "15:59:60-08:00", + "valid": true + }, + { + "description": "valid leap second, large negative time-offset", + "data": "00:29:60-23:30", + "valid": true + }, + { + "description": "invalid leap second, negative time-offset (wrong hour)", + "data": "23:59:60-01:00", + "valid": false + }, + { + "description": "invalid leap second, negative time-offset (wrong minute)", + "data": "23:59:60-00:30", + "valid": false + }, + { + "description": "a valid time string with second fraction", + "data": "23:20:50.52Z", + "valid": true + }, + { + "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { - "description": "an invalid time string", + "description": "a valid time string with plus offset", + "data": "08:30:06+00:20", + "valid": true + }, + { + "description": "a valid time string with minus offset", + "data": "08:30:06-08:00", + "valid": true + }, + { + "description": "a valid time string with case-insensitive Z", + "data": "08:30:06z", + "valid": true + }, + { + "description": "an invalid time string with invalid hour", + "data": "24:00:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid minute", + "data": "00:60:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid second", + "data": "00:00:61Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset hour", + "data": "01:02:03+24:00", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset minute", + "data": "01:02:03+00:60", + "valid": false + }, + { + "description": "an invalid time string with invalid time with both Z and numoffset", + "data": "01:02:03Z+00:30", + "valid": false + }, + { + "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, @@ -17,6 +182,16 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false + }, + { + "description": "no time offset", + "data": "12:00:00", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২:00:00Z", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/unknown.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/unknown.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/unknown.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/unknown.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,43 @@ +[ + { + "description": "unknown format", + "schema": { "format": "unknown" }, + "tests": [ + { + "description": "unknown formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "unknown formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "unknown formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "unknown formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "unknown formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "unknown formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "unknown formats ignore strings", + "data": "string", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uri.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,7 +1,7 @@ [ { "description": "validation of URIs", - "schema": {"format": "uri"}, + "schema": { "format": "uri" }, "tests": [ { "description": "a valid URL with anchor tag", @@ -9,7 +9,7 @@ "valid": true }, { - "description": "a valid URL with anchor tag and parantheses", + "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, @@ -97,6 +97,11 @@ "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uri-reference.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uri-reference.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uri-reference.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of URI References", - "schema": {"format": "uri-reference"}, + "schema": { "format": "uri-reference" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uri-template.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uri-template.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uri-template.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uri-template.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "format: uri-template", - "schema": {"format": "uri-template"}, + "schema": { "format": "uri-template" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uuid.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uuid.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/format/uuid.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/format/uuid.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,85 @@ +[ + { + "description": "uuid format", + "schema": { + "format": "uuid" + }, + "tests": [ + { + "description": "all upper-case", + "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", + "valid": true + }, + { + "description": "all lower-case", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", + "valid": true + }, + { + "description": "mixed case", + "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", + "valid": true + }, + { + "description": "all zeroes is valid", + "data": "00000000-0000-0000-0000-000000000000", + "valid": true + }, + { + "description": "wrong length", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": false + }, + { + "description": "missing section", + "data": "2eb8aa08-aa98-11ea-73b441d16380", + "valid": false + }, + { + "description": "bad characters (not hex)", + "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", + "valid": false + }, + { + "description": "no dashes", + "data": "2eb8aa08aa9811eab4aa73b441d16380", + "valid": false + }, + { + "description": "too few dashes", + "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", + "valid": false + }, + { + "description": "too many dashes", + "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", + "valid": false + }, + { + "description": "dashes in the wrong spot", + "data": "2eb8aa08aa9811eab4aa73b441d16380----", + "valid": false + }, + { + "description": "valid version 4", + "data": "98d80576-482e-427f-8434-7f86890ab222", + "valid": true + }, + { + "description": "valid version 5", + "data": "99c17cbb-656f-564a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 6", + "data": "99c17cbb-656f-664a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 15", + "data": "99c17cbb-656f-f64a-940f-1a4568f03487", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/refOfUnknownKeyword.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/refOfUnknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/refOfUnknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/refOfUnknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,44 @@ +[ + { + "description": "reference of a root arbitrary keyword ", + "schema": { + "unknown-keyword": {"type": "integer"}, + "properties": { + "bar": {"$ref": "#/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "reference of an arbitrary keyword of a sub-schema", + "schema": { + "properties": { + "foo": {"unknown-keyword": {"type": "integer"}}, + "bar": {"$ref": "#/properties/foo/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/optional/zeroTerminatedFloats.json python-jsonschema-4.6.0/json/tests/draft2019-09/optional/zeroTerminatedFloats.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/optional/zeroTerminatedFloats.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/optional/zeroTerminatedFloats.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -[ - { - "description": "some languages do not distinguish between different types of numeric value", - "schema": { - "type": "integer" - }, - "tests": [ - { - "description": "a float without fractional part is an integer", - "data": 1.0, - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/pattern.json python-jsonschema-4.6.0/json/tests/draft2019-09/pattern.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/pattern.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,9 +14,34 @@ "valid": false }, { - "description": "ignores non-strings", + "description": "ignores booleans", "data": true, "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true } ] }, diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/patternProperties.json python-jsonschema-4.6.0/json/tests/draft2019-09/patternProperties.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/patternProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/patternProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -142,6 +142,11 @@ "valid": false }, { + "description": "object with a property matching both true and false is invalid", + "data": {"foobar":1}, + "valid": false + }, + { "description": "empty object is valid", "data": {}, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/propertyNames.json python-jsonschema-4.6.0/json/tests/draft2019-09/propertyNames.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/propertyNames.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/propertyNames.json 2022-06-01 20:26:26.000000000 +0000 @@ -44,6 +44,35 @@ ] }, { + "description": "propertyNames validation with pattern", + "schema": { + "propertyNames": { "pattern": "^a+$" } + }, + "tests": [ + { + "description": "matching property names valid", + "data": { + "a": {}, + "aa": {}, + "aaa": {} + }, + "valid": true + }, + { + "description": "non-matching property name is invalid", + "data": { + "aaA": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + } + ] + }, + { "description": "propertyNames with boolean schema true", "schema": {"propertyNames": true}, "tests": [ diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/recursiveRef.json python-jsonschema-4.6.0/json/tests/draft2019-09/recursiveRef.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/recursiveRef.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/recursiveRef.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,399 @@ +[ + { + "description": "$recursiveRef without $recursiveAnchor works like $ref", + "schema": { + "properties": { + "foo": { "$recursiveRef": "#" } + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": { "foo": { "foo": false } }, + "valid": true + }, + { + "description": "mismatch", + "data": { "bar": false }, + "valid": false + }, + { + "description": "recursive mismatch", + "data": { "foo": { "bar": false } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef without using nesting", + "schema": { + "$id": "http://localhost:4242/recursiveRef2/schema.json", + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer does not match as a property value", + "data": { "foo": 1 }, + "valid": false + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, no match", + "data": { "foo": { "bar": 1 } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with nesting", + "schema": { + "$id": "http://localhost:4242/recursiveRef3/schema.json", + "$recursiveAnchor": true, + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer now matches as a property value", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, properties match with $recursiveRef", + "data": { "foo": { "bar": 1 } }, + "valid": true + } + ] + }, + { + "description": "$recursiveRef with $recursiveAnchor: false works like $ref", + "schema": { + "$id": "http://localhost:4242/recursiveRef4/schema.json", + "$recursiveAnchor": false, + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": false, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer does not match as a property value", + "data": { "foo": 1 }, + "valid": false + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, integer does not match as a property value", + "data": { "foo": { "bar": 1 } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with no $recursiveAnchor works like $ref", + "schema": { + "$id": "http://localhost:4242/recursiveRef5/schema.json", + "$defs": { + "myobject": { + "$id": "myobject.json", + "$recursiveAnchor": false, + "anyOf": [ + { "type": "string" }, + { + "type": "object", + "additionalProperties": { "$recursiveRef": "#" } + } + ] + } + }, + "anyOf": [ + { "type": "integer" }, + { "$ref": "#/$defs/myobject" } + ] + }, + "tests": [ + { + "description": "integer matches at the outer level", + "data": 1, + "valid": true + }, + { + "description": "single level match", + "data": { "foo": "hi" }, + "valid": true + }, + { + "description": "integer does not match as a property value", + "data": { "foo": 1 }, + "valid": false + }, + { + "description": "two levels, properties match with inner definition", + "data": { "foo": { "bar": "hi" } }, + "valid": true + }, + { + "description": "two levels, integer does not match as a property value", + "data": { "foo": { "bar": 1 } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with no $recursiveAnchor in the initial target schema resource", + "schema": { + "$id": "http://localhost:4242/recursiveRef6/base.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "boolean" }, + { + "type": "object", + "additionalProperties": { + "$id": "http://localhost:4242/recursiveRef6/inner.json", + "$comment": "there is no $recursiveAnchor: true here, so we do NOT recurse to the base", + "anyOf": [ + { "type": "integer" }, + { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } + ] + } + } + ] + }, + "tests": [ + { + "description": "leaf node does not match; no recursion", + "data": { "foo": true }, + "valid": false + }, + { + "description": "leaf node matches: recursion uses the inner schema", + "data": { "foo": { "bar": 1 } }, + "valid": true + }, + { + "description": "leaf node does not match: recursion uses the inner schema", + "data": { "foo": { "bar": true } }, + "valid": false + } + ] + }, + { + "description": "$recursiveRef with no $recursiveAnchor in the outer schema resource", + "schema": { + "$id": "http://localhost:4242/recursiveRef7/base.json", + "anyOf": [ + { "type": "boolean" }, + { + "type": "object", + "additionalProperties": { + "$id": "http://localhost:4242/recursiveRef7/inner.json", + "$recursiveAnchor": true, + "anyOf": [ + { "type": "integer" }, + { "type": "object", "additionalProperties": { "$recursiveRef": "#" } } + ] + } + } + ] + }, + "tests": [ + { + "description": "leaf node does not match; no recursion", + "data": { "foo": true }, + "valid": false + }, + { + "description": "leaf node matches: recursion only uses inner schema", + "data": { "foo": { "bar": 1 } }, + "valid": true + }, + { + "description": "leaf node does not match: recursion only uses inner schema", + "data": { "foo": { "bar": true } }, + "valid": false + } + ] + }, + { + "description": "multiple dynamic paths to the $recursiveRef keyword", + "schema": { + "$id": "recursiveRef8_main.json", + "$defs": { + "inner": { + "$id": "recursiveRef8_inner.json", + "$recursiveAnchor": true, + "title": "inner", + "additionalProperties": { + "$recursiveRef": "#" + } + } + }, + "if": { + "propertyNames": { + "pattern": "^[a-m]" + } + }, + "then": { + "title": "any type of node", + "$id": "recursiveRef8_anyLeafNode.json", + "$recursiveAnchor": true, + "$ref": "recursiveRef8_inner.json" + }, + "else": { + "title": "integer node", + "$id": "recursiveRef8_integerNode.json", + "$recursiveAnchor": true, + "type": [ "object", "integer" ], + "$ref": "recursiveRef8_inner.json" + } + }, + "tests": [ + { + "description": "recurse to anyLeafNode - floats are allowed", + "data": { "alpha": 1.1 }, + "valid": true + }, + { + "description": "recurse to integerNode - floats are not allowed", + "data": { "november": 1.1 }, + "valid": false + } + ] + }, + { + "description": "dynamic $recursiveRef destination (not predictable at schema compile time)", + "schema": { + "$id": "main.json", + "$defs": { + "inner": { + "$id": "inner.json", + "$recursiveAnchor": true, + "title": "inner", + "additionalProperties": { + "$recursiveRef": "#" + } + } + + }, + "if": { "propertyNames": { "pattern": "^[a-m]" } }, + "then": { + "title": "any type of node", + "$id": "anyLeafNode.json", + "$recursiveAnchor": true, + "$ref": "main.json#/$defs/inner" + }, + "else": { + "title": "integer node", + "$id": "integerNode.json", + "$recursiveAnchor": true, + "type": [ "object", "integer" ], + "$ref": "main.json#/$defs/inner" + } + }, + "tests": [ + { + "description": "numeric node", + "data": { "alpha": 1.1 }, + "valid": true + }, + { + "description": "integer node", + "data": { "november": 1.1 }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/ref.json python-jsonschema-4.6.0/json/tests/draft2019-09/ref.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/ref.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "$defs": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/$defs/tilde~0field"}, + "slash": {"$ref": "#/$defs/slash~1field"}, + "percent": {"$ref": "#/$defs/percent%25field"} } }, "tests": [ @@ -91,8 +93,8 @@ "valid": false }, { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, "valid": false }, { @@ -106,8 +108,8 @@ "valid": true }, { - "description": "tilda valid", - "data": {"tilda": 123}, + "description": "tilde valid", + "data": {"tilde": 123}, "valid": true }, { @@ -141,7 +143,7 @@ ] }, { - "description": "ref overrides any sibling keywords", + "description": "ref applies alongside sibling keywords", "schema": { "$defs": { "reffed": { @@ -157,14 +159,14 @@ }, "tests": [ { - "description": "ref valid", + "description": "ref valid, maxItems valid", "data": { "foo": [] }, "valid": true }, { - "description": "ref valid, maxItems ignored", - "data": { "foo": [ 1, 2, 3] }, - "valid": true + "description": "ref valid, maxItems invalid", + "data": { "foo": [1, 2, 3] }, + "valid": false }, { "description": "ref invalid", @@ -210,6 +212,31 @@ ] }, { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/$defs/is-string"} + }, + "$defs": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { "description": "$ref to boolean schema true", "schema": { "$ref": "#/$defs/bool", @@ -355,5 +382,198 @@ "valid": false } ] + }, + { + "description": "ref creates new scope when adjacent to keywords", + "schema": { + "$defs": { + "A": { + "unevaluatedProperties": false + } + }, + "properties": { + "prop1": { + "type": "string" + } + }, + "$ref": "#/$defs/A" + }, + "tests": [ + { + "description": "referenced subschema doesn't see annotations from properties", + "data": { + "prop1": "match" + }, + "valid": false + } + ] + }, + { + "description": "naive replacement of $ref with its destination is not correct", + "schema": { + "$defs": { + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/$defs/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "do not evaluate the $ref inside the enum, definition exact match", + "data": { "type": "string" }, + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/$defs/a_string" }, + "valid": true + } + ] + }, + { + "description": "refs with relative uris and defs", + "schema": { + "$id": "http://example.com/schema-relative-uri-defs1.json", + "properties": { + "foo": { + "$id": "schema-relative-uri-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-relative-uri-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "relative refs with absolute uris and defs", + "schema": { + "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", + "properties": { + "foo": { + "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-refs-absolute-uris-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "$id must be resolved against nearest parent, not just immediate parent", + "schema": { + "$id": "http://example.com/a.json", + "$defs": { + "x": { + "$id": "http://example.com/b/c.json", + "not": { + "$defs": { + "y": { + "$id": "d.json", + "type": "number" + } + } + } + } + }, + "allOf": [ + { + "$ref": "http://example.com/b/d.json" + } + ] + }, + "tests": [ + { + "description": "number should pass", + "data": 1, + "valid": true + }, + { + "description": "non-number should fail", + "data": "a", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/refRemote.json python-jsonschema-4.6.0/json/tests/draft2019-09/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/refRemote.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "schema": {"$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + "$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/refToInteger" }, "tests": [ { @@ -54,7 +54,7 @@ "schema": { "$id": "http://localhost:1234/", "items": { - "$id": "folder/", + "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, @@ -76,10 +76,10 @@ "schema": { "$id": "http://localhost:1234/scope_change_defs1.json", "type" : "object", - "properties": {"list": {"$ref": "#/$defs/baz"}}, + "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, "$defs": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } @@ -103,10 +103,10 @@ "schema": { "$id": "http://localhost:1234/scope_change_defs2.json", "type" : "object", - "properties": {"list": {"$ref": "#/$defs/baz/$defs/bar"}}, + "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, "$defs": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolderInSubschema/", "$defs": { "bar": { "type": "array", @@ -163,5 +163,28 @@ "valid": false } ] + }, + { + "description": "remote ref with ref to defs", + "schema": { + "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", + "$ref": "ref-and-defs.json" + }, + "tests": [ + { + "description": "invalid", + "data": { + "bar": 1 + }, + "valid": false + }, + { + "description": "valid", + "data": { + "bar": "a" + }, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/type.json python-jsonschema-4.6.0/json/tests/draft2019-09/type.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/type.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -9,6 +9,11 @@ "valid": true }, { + "description": "a float with zero fractional part is an integer", + "data": 1.0, + "valid": true + }, + { "description": "a float is not an integer", "data": 1.1, "valid": false @@ -55,6 +60,11 @@ "valid": true }, { + "description": "a float with zero fractional part is a number (and an integer)", + "data": 1.0, + "valid": true + }, + { "description": "a float is a number", "data": 1.1, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/unevaluatedItems.json python-jsonschema-4.6.0/json/tests/draft2019-09/unevaluatedItems.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/unevaluatedItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/unevaluatedItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,525 @@ +[ + { + "description": "unevaluatedItems true", + "schema": { + "type": "array", + "unevaluatedItems": true + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems false", + "schema": { + "type": "array", + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems as schema", + "schema": { + "type": "array", + "unevaluatedItems": { "type": "string" } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with valid unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with invalid unevaluated items", + "data": [42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with uniform items", + "schema": { + "type": "array", + "items": { "type": "string" }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", "bar"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with tuple", + "schema": { + "type": "array", + "items": [ + { "type": "string" } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with additionalItems", + "schema": { + "type": "array", + "items": [ + { "type": "string" } + ], + "additionalItems": true, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested tuple", + "schema": { + "type": "array", + "items": [ + { "type": "string" } + ], + "allOf": [ + { + "items": [ + true, + { "type": "number" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", 42], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", 42, true], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with nested additionalItems", + "schema": { + "type": "array", + "allOf": [ + { + "items": [ + { "type": "string" } + ], + "additionalItems": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested unevaluatedItems", + "schema": { + "type": "array", + "allOf": [ + { + "items": [ + { "type": "string" } + ] + }, + { + "unevaluatedItems": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with anyOf", + "schema": { + "type": "array", + "items": [ + { "const": "foo" } + ], + "anyOf": [ + { + "items": [ + true, + { "const": "bar" } + ] + }, + { + "items": [ + true, + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when one schema matches and has no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "when one schema matches and has unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + }, + { + "description": "when two schemas match and has no unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "when two schemas match and has unevaluated items", + "data": ["foo", "bar", "baz", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with oneOf", + "schema": { + "type": "array", + "items": [ + { "const": "foo" } + ], + "oneOf": [ + { + "items": [ + true, + { "const": "bar" } + ] + }, + { + "items": [ + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with not", + "schema": { + "type": "array", + "items": [ + { "const": "foo" } + ], + "not": { + "not": { + "items": [ + true, + { "const": "bar" } + ] + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with if/then/else", + "schema": { + "type": "array", + "items": [ + { "const": "foo" } + ], + "if": { + "items": [ + true, + { "const": "bar" } + ] + }, + "then": { + "items": [ + true, + true, + { "const": "then" } + ] + }, + "else": { + "items": [ + true, + true, + true, + { "const": "else" } + ] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when if matches and it has no unevaluated items", + "data": ["foo", "bar", "then"], + "valid": true + }, + { + "description": "when if matches and it has unevaluated items", + "data": ["foo", "bar", "then", "else"], + "valid": false + }, + { + "description": "when if doesn't match and it has no unevaluated items", + "data": ["foo", 42, 42, "else"], + "valid": true + }, + { + "description": "when if doesn't match and it has unevaluated items", + "data": ["foo", 42, 42, "else", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with boolean schemas", + "schema": { + "type": "array", + "allOf": [true], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $ref", + "schema": { + "type": "array", + "$ref": "#/$defs/bar", + "items": [ + { "type": "string" } + ], + "unevaluatedItems": false, + "$defs": { + "bar": { + "items": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems can't see inside cousins", + "schema": { + "allOf": [ + { + "items": [ true ] + }, + { + "unevaluatedItems": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": [ 1 ], + "valid": false + } + ] + }, + { + "description": "item is evaluated in an uncle schema to unevaluatedItems", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "items": [ + { + "type": "string" + } + ], + "unevaluatedItems": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "items": [ + true, + { + "type": "string" + } + ] + } + } + } + ] + }, + "tests": [ + { + "description": "no extra items", + "data": { + "foo": [ + "test" + ] + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": [ + "test", + "test" + ] + }, + "valid": false + } + ] + }, + { + "description": "non-array instances are valid", + "schema": {"unevaluatedItems": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/unevaluatedProperties.json python-jsonschema-4.6.0/json/tests/draft2019-09/unevaluatedProperties.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/unevaluatedProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/unevaluatedProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,1347 @@ +[ + { + "description": "unevaluatedProperties true", + "schema": { + "type": "object", + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties schema", + "schema": { + "type": "object", + "unevaluatedProperties": { + "type": "string", + "minLength": 3 + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with valid unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with invalid unevaluated properties", + "data": { + "foo": "fo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties false", + "schema": { + "type": "object", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent patternProperties", + "schema": { + "type": "object", + "patternProperties": { + "^foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "additionalProperties": true, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "properties": { + "bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested patternProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "patternProperties": { + "^bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "additionalProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested unevaluatedProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": { + "type": "string", + "maxLength": 2 + } + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with anyOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "anyOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + }, + { + "properties": { + "quux": { "const": "quux" } + }, + "required": ["quux"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when one matches and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when one matches and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "not-baz" + }, + "valid": false + }, + { + "description": "when two match and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": true + }, + { + "description": "when two match and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz", + "quux": "not-quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with oneOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "oneOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "quux": "quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with not", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "not": { + "not": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, then not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": false + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, else not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with dependentSchemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with boolean schemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [true], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $ref", + "schema": { + "type": "object", + "$ref": "#/$defs/bar", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false, + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties can't see inside cousins", + "schema": { + "allOf": [ + { + "properties": { + "foo": true + } + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": { + "foo": 1 + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, true with properties", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, false with properties", + "schema": { + "type": "object", + "allOf": [ + { + "unevaluatedProperties": true + }, + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "property is evaluated in an uncle schema to unevaluatedProperties", + "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + }, + "unevaluatedProperties": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "properties": { + "faz": { + "type": "string" + } + } + } + } + } + ] + }, + "tests": [ + { + "description": "no extra properties", + "data": { + "foo": { + "bar": "test" + } + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": { + "bar": "test", + "faz": "test" + } + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, allOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + }, + "unevaluatedProperties": false + } + ], + "anyOf": [ + { + "properties": { + "bar": true + } + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": true + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, anyOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + } + } + ], + "anyOf": [ + { + "properties": { + "bar": true + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties + single cyclic ref", + "schema": { + "type": "object", + "properties": { + "x": { "$ref": "#" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is valid", + "data": {}, + "valid": true + }, + { + "description": "Single is valid", + "data": { "x": {} }, + "valid": true + }, + { + "description": "Unevaluated on 1st level is invalid", + "data": { "x": {}, "y": {} }, + "valid": false + }, + { + "description": "Nested is valid", + "data": { "x": { "x": {} } }, + "valid": true + }, + { + "description": "Unevaluated on 2nd level is invalid", + "data": { "x": { "x": {}, "y": {} } }, + "valid": false + }, + { + "description": "Deep nested is valid", + "data": { "x": { "x": { "x": {} } } }, + "valid": true + }, + { + "description": "Unevaluated on 3rd level is invalid", + "data": { "x": { "x": { "x": {}, "y": {} } } }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties + ref inside allOf / oneOf", + "schema": { + "$defs": { + "one": { + "properties": { "a": true } + }, + "two": { + "required": ["x"], + "properties": { "x": true } + } + }, + "allOf": [ + { "$ref": "#/$defs/one" }, + { "properties": { "b": true } }, + { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { + "required": ["y"], + "properties": { "y": true } + } + ] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid (no x or y)", + "data": {}, + "valid": false + }, + { + "description": "a and b are invalid (no x or y)", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "x and y are invalid", + "data": { "x": 1, "y": 1 }, + "valid": false + }, + { + "description": "a and x are valid", + "data": { "a": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and y are valid", + "data": { "a": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x are valid", + "data": { "a": 1, "b": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and b and y are valid", + "data": { "a": 1, "b": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x and y are invalid", + "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, + "valid": false + } + ] + }, + { + "description": "dynamic evalation inside nested refs", + "schema": { + "$defs": { + "one": { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { "required": ["b"], "properties": { "b": true } }, + { "required": ["xx"], "patternProperties": { "x": true } }, + { "required": ["all"], "unevaluatedProperties": true } + ] + }, + "two": { + "oneOf": [ + { "required": ["c"], "properties": { "c": true } }, + { "required": ["d"], "properties": { "d": true } } + ] + } + }, + "oneOf": [ + { "$ref": "#/$defs/one" }, + { "required": ["a"], "properties": { "a": true } } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid", + "data": {}, + "valid": false + }, + { + "description": "a is valid", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "b is valid", + "data": { "b": 1 }, + "valid": true + }, + { + "description": "c is valid", + "data": { "c": 1 }, + "valid": true + }, + { + "description": "d is valid", + "data": { "d": 1 }, + "valid": true + }, + { + "description": "a + b is invalid", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "a + c is invalid", + "data": { "a": 1, "c": 1 }, + "valid": false + }, + { + "description": "a + d is invalid", + "data": { "a": 1, "d": 1 }, + "valid": false + }, + { + "description": "b + c is invalid", + "data": { "b": 1, "c": 1 }, + "valid": false + }, + { + "description": "b + d is invalid", + "data": { "b": 1, "d": 1 }, + "valid": false + }, + { + "description": "c + d is invalid", + "data": { "c": 1, "d": 1 }, + "valid": false + }, + { + "description": "xx is valid", + "data": { "xx": 1 }, + "valid": true + }, + { + "description": "xx + foox is valid", + "data": { "xx": 1, "foox": 1 }, + "valid": true + }, + { + "description": "xx + foo is invalid", + "data": { "xx": 1, "foo": 1 }, + "valid": false + }, + { + "description": "xx + a is invalid", + "data": { "xx": 1, "a": 1 }, + "valid": false + }, + { + "description": "xx + b is invalid", + "data": { "xx": 1, "b": 1 }, + "valid": false + }, + { + "description": "xx + c is invalid", + "data": { "xx": 1, "c": 1 }, + "valid": false + }, + { + "description": "xx + d is invalid", + "data": { "xx": 1, "d": 1 }, + "valid": false + }, + { + "description": "all is valid", + "data": { "all": 1 }, + "valid": true + }, + { + "description": "all + foo is valid", + "data": { "all": 1, "foo": 1 }, + "valid": true + }, + { + "description": "all + a is invalid", + "data": { "all": 1, "a": 1 }, + "valid": false + } + ] + }, + { + "description": "non-object instances are valid", + "schema": {"unevaluatedProperties": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft2019-09/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/uniqueItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,6 +14,11 @@ "valid": false }, { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false @@ -29,6 +34,16 @@ "valid": true }, { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true @@ -65,6 +80,11 @@ "valid": false }, { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { "description": "1 and true are unique", "data": [1, true], "valid": true @@ -75,21 +95,61 @@ "valid": true }, { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], + "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], + "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ @@ -138,8 +198,8 @@ { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], - "uniqueItems": true, + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, "additionalItems": false }, "tests": [ @@ -165,6 +225,177 @@ }, { "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/unknownKeyword.json python-jsonschema-4.6.0/json/tests/draft2019-09/unknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/unknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/unknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,56 @@ +[ + { + "description": "$id inside an unknown keyword is not a real identifier", + "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", + "schema": { + "$defs": { + "id_in_unknown0": { + "not": { + "array_of_schemas": [ + { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "null" + } + ] + } + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "string" + }, + "id_in_unknown1": { + "not": { + "object_of_schemas": { + "foo": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "integer" + } + } + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_unknown0" }, + { "$ref": "#/$defs/id_in_unknown1" }, + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "type matches second anyOf, which has a real schema in it", + "data": "a string", + "valid": true + }, + { + "description": "type matches non-schema in first anyOf", + "data": null, + "valid": false + }, + { + "description": "type matches non-schema in third anyOf", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2019-09/vocabulary.json python-jsonschema-4.6.0/json/tests/draft2019-09/vocabulary.json --- python-jsonschema-3.2.0/json/tests/draft2019-09/vocabulary.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2019-09/vocabulary.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "schema that uses custom metaschema with with no validation vocabulary", + "schema": { + "$id": "https://schema/using/no/validation", + "$schema": "http://localhost:1234/draft2019-09/metaschema-no-validation.json", + "properties": { + "badProperty": false, + "numberProperty": { + "minimum": 10 + } + } + }, + "tests": [ + { + "description": "applicator vocabulary still works", + "data": { + "badProperty": "this property should not exist" + }, + "valid": false + }, + { + "description": "no validation: valid number", + "data": { + "numberProperty": 20 + }, + "valid": true + }, + { + "description": "no validation: invalid number, but it still validates", + "data": { + "numberProperty": 1 + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft2020-12/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/additionalProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,133 @@ +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobarbaz", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": "non-ASCII pattern with additionalProperties", + "schema": { + "patternProperties": {"^á": {}}, + "additionalProperties": false + }, + "tests": [ + { + "description": "matching the pattern is valid", + "data": {"ármányos": 2}, + "valid": true + }, + { + "description": "not matching the pattern is invalid", + "data": {"élmény": 2}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + }, + { + "description": "additionalProperties should not look in applicators", + "schema": { + "allOf": [ + {"properties": {"foo": {}}} + ], + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "properties defined in allOf are not examined", + "data": {"foo": 1, "bar": true}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/allOf.json python-jsonschema-4.6.0/json/tests/draft2020-12/allOf.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/allOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,294 @@ +[ + { + "description": "allOf", + "schema": { + "allOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "allOf", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch second", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch first", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "allOf with base schema", + "schema": { + "properties": {"bar": {"type": "integer"}}, + "required": ["bar"], + "allOf" : [ + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + }, + { + "properties": { + "baz": {"type": "null"} + }, + "required": ["baz"] + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch base schema", + "data": {"foo": "quux", "baz": null}, + "valid": false + }, + { + "description": "mismatch first allOf", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second allOf", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "allOf simple types", + "schema": { + "allOf": [ + {"maximum": 30}, + {"minimum": 20} + ] + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch one", + "data": 35, + "valid": false + } + ] + }, + { + "description": "allOf with boolean schemas, all true", + "schema": {"allOf": [true, true]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "allOf with boolean schemas, some false", + "schema": {"allOf": [true, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "allOf with boolean schemas, all false", + "schema": {"allOf": [false, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "allOf with one empty schema", + "schema": { + "allOf": [ + {} + ] + }, + "tests": [ + { + "description": "any data is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "allOf with two empty schemas", + "schema": { + "allOf": [ + {}, + {} + ] + }, + "tests": [ + { + "description": "any data is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "allOf with the first empty schema", + "schema": { + "allOf": [ + {}, + { "type": "number" } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "allOf with the last empty schema", + "schema": { + "allOf": [ + { "type": "number" }, + {} + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/anchor.json python-jsonschema-4.6.0/json/tests/draft2020-12/anchor.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/anchor.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/anchor.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,173 @@ +[ + { + "description": "Location-independent identifier", + "schema": { + "$ref": "#foo", + "$defs": { + "A": { + "$anchor": "foo", + "type": "integer" + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "Location-independent identifier with absolute URI", + "schema": { + "$ref": "http://localhost:1234/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar", + "$anchor": "foo", + "type": "integer" + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "Location-independent identifier with base URI change in subschema", + "schema": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$anchor": "foo", + "type": "integer" + } + } + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, + { + "description": "same $anchor with different base uri", + "schema": { + "$id": "http://localhost:1234/foobar", + "$defs": { + "A": { + "$id": "child1", + "allOf": [ + { + "$id": "child2", + "$anchor": "my_anchor", + "type": "number" + }, + { + "$anchor": "my_anchor", + "type": "string" + } + ] + } + }, + "$ref": "child1#my_anchor" + }, + "tests": [ + { + "description": "$ref should resolve to /$defs/A/allOf/1", + "data": "a", + "valid": true + }, + { + "description": "$ref should not resolve to /$defs/A/allOf/0", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/anyOf.json python-jsonschema-4.6.0/json/tests/draft2020-12/anyOf.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/anyOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/anyOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,189 @@ +[ + { + "description": "anyOf", + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first anyOf valid", + "data": 1, + "valid": true + }, + { + "description": "second anyOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both anyOf valid", + "data": 3, + "valid": true + }, + { + "description": "neither anyOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "anyOf with base schema", + "schema": { + "type": "string", + "anyOf" : [ + { + "maxLength": 2 + }, + { + "minLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one anyOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both anyOf invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "anyOf with boolean schemas, all true", + "schema": {"anyOf": [true, true]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "anyOf with boolean schemas, some true", + "schema": {"anyOf": [true, false]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "anyOf with boolean schemas, all false", + "schema": {"anyOf": [false, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "anyOf complex types", + "schema": { + "anyOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first anyOf valid (complex)", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "second anyOf valid (complex)", + "data": {"foo": "baz"}, + "valid": true + }, + { + "description": "both anyOf valid (complex)", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "neither anyOf valid (complex)", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "anyOf with one empty schema", + "schema": { + "anyOf": [ + { "type": "number" }, + {} + ] + }, + "tests": [ + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "number is valid", + "data": 123, + "valid": true + } + ] + }, + { + "description": "nested anyOf, to check validation semantics", + "schema": { + "anyOf": [ + { + "anyOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/boolean_schema.json python-jsonschema-4.6.0/json/tests/draft2020-12/boolean_schema.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/boolean_schema.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/boolean_schema.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,104 @@ +[ + { + "description": "boolean schema 'true'", + "schema": true, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "boolean schema 'false'", + "schema": false, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/const.json python-jsonschema-4.6.0/json/tests/draft2020-12/const.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/const.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/const.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,342 @@ +[ + { + "description": "const validation", + "schema": {"const": 2}, + "tests": [ + { + "description": "same value is valid", + "data": 2, + "valid": true + }, + { + "description": "another value is invalid", + "data": 5, + "valid": false + }, + { + "description": "another type is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "const with object", + "schema": {"const": {"foo": "bar", "baz": "bax"}}, + "tests": [ + { + "description": "same object is valid", + "data": {"foo": "bar", "baz": "bax"}, + "valid": true + }, + { + "description": "same object with different property order is valid", + "data": {"baz": "bax", "foo": "bar"}, + "valid": true + }, + { + "description": "another object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "another type is invalid", + "data": [1, 2], + "valid": false + } + ] + }, + { + "description": "const with array", + "schema": {"const": [{ "foo": "bar" }]}, + "tests": [ + { + "description": "same array is valid", + "data": [{"foo": "bar"}], + "valid": true + }, + { + "description": "another array item is invalid", + "data": [2], + "valid": false + }, + { + "description": "array with additional items is invalid", + "data": [1, 2, 3], + "valid": false + } + ] + }, + { + "description": "const with null", + "schema": {"const": null}, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "not null is invalid", + "data": 0, + "valid": false + } + ] + }, + { + "description": "const with false does not match 0", + "schema": {"const": false}, + "tests": [ + { + "description": "false is valid", + "data": false, + "valid": true + }, + { + "description": "integer zero is invalid", + "data": 0, + "valid": false + }, + { + "description": "float zero is invalid", + "data": 0.0, + "valid": false + } + ] + }, + { + "description": "const with true does not match 1", + "schema": {"const": true}, + "tests": [ + { + "description": "true is valid", + "data": true, + "valid": true + }, + { + "description": "integer one is invalid", + "data": 1, + "valid": false + }, + { + "description": "float one is invalid", + "data": 1.0, + "valid": false + } + ] + }, + { + "description": "const with [false] does not match [0]", + "schema": {"const": [false]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, + { + "description": "const with [true] does not match [1]", + "schema": {"const": [true]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, + { + "description": "const with {\"a\": false} does not match {\"a\": 0}", + "schema": {"const": {"a": false}}, + "tests": [ + { + "description": "{\"a\": false} is valid", + "data": {"a": false}, + "valid": true + }, + { + "description": "{\"a\": 0} is invalid", + "data": {"a": 0}, + "valid": false + }, + { + "description": "{\"a\": 0.0} is invalid", + "data": {"a": 0.0}, + "valid": false + } + ] + }, + { + "description": "const with {\"a\": true} does not match {\"a\": 1}", + "schema": {"const": {"a": true}}, + "tests": [ + { + "description": "{\"a\": true} is valid", + "data": {"a": true}, + "valid": true + }, + { + "description": "{\"a\": 1} is invalid", + "data": {"a": 1}, + "valid": false + }, + { + "description": "{\"a\": 1.0} is invalid", + "data": {"a": 1.0}, + "valid": false + } + ] + }, + { + "description": "const with 0 does not match other zero-like types", + "schema": {"const": 0}, + "tests": [ + { + "description": "false is invalid", + "data": false, + "valid": false + }, + { + "description": "integer zero is valid", + "data": 0, + "valid": true + }, + { + "description": "float zero is valid", + "data": 0.0, + "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "empty string is invalid", + "data": "", + "valid": false + } + ] + }, + { + "description": "const with 1 does not match true", + "schema": {"const": 1}, + "tests": [ + { + "description": "true is invalid", + "data": true, + "valid": false + }, + { + "description": "integer one is valid", + "data": 1, + "valid": true + }, + { + "description": "float one is valid", + "data": 1.0, + "valid": true + } + ] + }, + { + "description": "const with -2.0 matches integer and float types", + "schema": {"const": -2.0}, + "tests": [ + { + "description": "integer -2 is valid", + "data": -2, + "valid": true + }, + { + "description": "integer 2 is invalid", + "data": 2, + "valid": false + }, + { + "description": "float -2.0 is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float 2.0 is invalid", + "data": 2.0, + "valid": false + }, + { + "description": "float -2.00001 is invalid", + "data": -2.00001, + "valid": false + } + ] + }, + { + "description": "float and integers are equal up to 64-bit representation limits", + "schema": {"const": 9007199254740992}, + "tests": [ + { + "description": "integer is valid", + "data": 9007199254740992, + "valid": true + }, + { + "description": "integer minus one is invalid", + "data": 9007199254740991, + "valid": false + }, + { + "description": "float is valid", + "data": 9007199254740992.0, + "valid": true + }, + { + "description": "float minus one is invalid", + "data": 9007199254740991.0, + "valid": false + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "const": "hello\u0000there" }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/contains.json python-jsonschema-4.6.0/json/tests/draft2020-12/contains.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/contains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/contains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,150 @@ +[ + { + "description": "contains keyword validation", + "schema": { + "contains": {"minimum": 5} + }, + "tests": [ + { + "description": "array with item matching schema (5) is valid", + "data": [3, 4, 5], + "valid": true + }, + { + "description": "array with item matching schema (6) is valid", + "data": [3, 4, 6], + "valid": true + }, + { + "description": "array with two items matching schema (5, 6) is valid", + "data": [3, 4, 5, 6], + "valid": true + }, + { + "description": "array without items matching schema is invalid", + "data": [2, 3, 4], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "not array is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "contains keyword with const keyword", + "schema": { + "contains": { "const": 5 } + }, + "tests": [ + { + "description": "array with item 5 is valid", + "data": [3, 4, 5], + "valid": true + }, + { + "description": "array with two items 5 is valid", + "data": [3, 4, 5, 5], + "valid": true + }, + { + "description": "array without item 5 is invalid", + "data": [1, 2, 3, 4], + "valid": false + } + ] + }, + { + "description": "contains keyword with boolean schema true", + "schema": {"contains": true}, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "contains keyword with boolean schema false", + "schema": {"contains": false}, + "tests": [ + { + "description": "any non-empty array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "non-arrays are valid", + "data": "contains does not apply to strings", + "valid": true + } + ] + }, + { + "description": "items + contains", + "schema": { + "items": { "multipleOf": 2 }, + "contains": { "multipleOf": 3 } + }, + "tests": [ + { + "description": "matches items, does not match contains", + "data": [ 2, 4, 8 ], + "valid": false + }, + { + "description": "does not match items, matches contains", + "data": [ 3, 6, 9 ], + "valid": false + }, + { + "description": "matches both items and contains", + "data": [ 6, 12 ], + "valid": true + }, + { + "description": "matches neither items nor contains", + "data": [ 1, 5 ], + "valid": false + } + ] + }, + { + "description": "contains with false if subschema", + "schema": { + "contains": { + "if": false, + "else": true + } + }, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/content.json python-jsonschema-4.6.0/json/tests/draft2020-12/content.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/content.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/content.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,127 @@ +[ + { + "description": "validation of string-encoded content based on media type", + "schema": { + "contentMediaType": "application/json" + }, + "tests": [ + { + "description": "a valid JSON document", + "data": "{\"foo\": \"bar\"}", + "valid": true + }, + { + "description": "an invalid JSON document; validates true", + "data": "{:}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary string-encoding", + "schema": { + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64 string", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "an invalid base64 string (% is not a valid character); validates true", + "data": "eyJmb28iOi%iYmFyIn0K", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents with schema", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64", + "contentSchema": { "required": ["foo"], "properties": { "foo": { "type": "string" } } } + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "another valid base64-encoded JSON document", + "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", + "valid": true + }, + { + "description": "an invalid base64-encoded JSON document; validates true", + "data": "eyJib28iOiAyMH0=", + "valid": true + }, + { + "description": "an empty object as a base64-encoded JSON document; validates true", + "data": "e30=", + "valid": true + }, + { + "description": "an empty array as a base64-encoded JSON document", + "data": "W10=", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/default.json python-jsonschema-4.6.0/json/tests/draft2020-12/default.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/default.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,79 @@ +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/defs.json python-jsonschema-4.6.0/json/tests/draft2020-12/defs.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/defs.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/defs.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,20 @@ +[ + { + "description": "validate definition against metaschema", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "valid definition schema", + "data": {"$defs": {"foo": {"type": "integer"}}}, + "valid": true + }, + { + "description": "invalid definition schema", + "data": {"$defs": {"foo": {"type": 1}}}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/dependentRequired.json python-jsonschema-4.6.0/json/tests/draft2020-12/dependentRequired.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/dependentRequired.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/dependentRequired.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,142 @@ +[ + { + "description": "single dependency", + "schema": {"dependentRequired": {"bar": ["foo"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "empty dependents", + "schema": {"dependentRequired": {"bar": []}}, + "tests": [ + { + "description": "empty object", + "data": {}, + "valid": true + }, + { + "description": "object with one property", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "non-object is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "multiple dependents required", + "schema": {"dependentRequired": {"quux": ["foo", "bar"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentRequired": { + "foo\nbar": ["foo\rbar"], + "foo\"bar": ["foo'bar"] + } + }, + "tests": [ + { + "description": "CRLF", + "data": { + "foo\nbar": 1, + "foo\rbar": 2 + }, + "valid": true + }, + { + "description": "quoted quotes", + "data": { + "foo'bar": 1, + "foo\"bar": 2 + }, + "valid": true + }, + { + "description": "CRLF missing dependent", + "data": { + "foo\nbar": 1, + "foo": 2 + }, + "valid": false + }, + { + "description": "quoted quotes missing dependent", + "data": { + "foo\"bar": 2 + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/dependentSchemas.json python-jsonschema-4.6.0/json/tests/draft2020-12/dependentSchemas.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/dependentSchemas.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/dependentSchemas.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,129 @@ +[ + { + "description": "single dependency", + "schema": { + "dependentSchemas": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "boolean subschemas", + "schema": { + "dependentSchemas": { + "foo": true, + "bar": false + } + }, + "tests": [ + { + "description": "object with property having schema true is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property having schema false is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "object with both properties is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentSchemas": { + "foo\tbar": {"minProperties": 4}, + "foo'bar": {"required": ["foo\"bar"]} + } + }, + "tests": [ + { + "description": "quoted tab", + "data": { + "foo\tbar": 1, + "a": 2, + "b": 3, + "c": 4 + }, + "valid": true + }, + { + "description": "quoted quote", + "data": { + "foo'bar": {"foo\"bar": 1} + }, + "valid": false + }, + { + "description": "quoted tab invalid under dependent schema", + "data": { + "foo\tbar": 1, + "a": 2 + }, + "valid": false + }, + { + "description": "quoted quote invalid under dependent schema", + "data": {"foo'bar": 1}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/dynamicRef.json python-jsonschema-4.6.0/json/tests/draft2020-12/dynamicRef.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/dynamicRef.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/dynamicRef.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,619 @@ +[ + { + "description": "A $dynamicRef to a $dynamicAnchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef to an $anchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamicRef-anchor-same-schema/root", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "foo": { + "$anchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $ref to a $dynamicAnchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root", + "type": "array", + "items": { "$ref": "#items" }, + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef should resolve to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated", + "schema": { + "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to satisfy the bookending requirement", + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor should not affect dynamic scope resolution", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root", + "$ref": "intermediate-scope", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "intermediate-scope": { + "$id": "intermediate-scope", + "$ref": "list" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to satisfy the bookending requirement", + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "An $anchor with the same name as a $dynamicAnchor should not be used for dynamic scope resolution", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root", + "$ref": "list", + "$defs": { + "foo": { + "$anchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to satisfy the bookending requirement", + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef without a matching $dynamicAnchor in the same schema resource should behave like a normal $ref to $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-without-bookend/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref", + "$anchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef with a non-matching $dynamicAnchor in the same schema resource should behave like a normal $ref to $anchor", + "schema": { + "$id": "https://test.json-schema.org/unmatched-dynamic-anchor/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref", + "$anchor": "items", + "$dynamicAnchor": "foo" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor should resolve to the first $dynamicAnchor in the dynamic scope", + "schema": { + "$id": "https://test.json-schema.org/relative-dynamic-reference/root", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "foo": { "const": "pass" } + }, + "$ref": "extended", + "$defs": { + "extended": { + "$id": "extended", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "bar": { "$ref": "bar" } + } + }, + "bar": { + "$id": "bar", + "type": "object", + "properties": { + "baz": { "$dynamicRef": "extended#meta" } + } + } + } + }, + "tests": [ + { + "description": "The recursive part is valid against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "pass" } + } + }, + "valid": true + }, + { + "description": "The recursive part is not valid against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "fail" } + } + }, + "valid": false + } + ] + }, + { + "description": "A $dynamicRef that initially resolves to a schema without a matching $dynamicAnchor should behave like a normal $ref to $anchor", + "schema": { + "$id": "https://test.json-schema.org/relative-dynamic-reference-without-bookend/root", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "foo": { "const": "pass" } + }, + "$ref": "extended", + "$defs": { + "extended": { + "$id": "extended", + "$anchor": "meta", + "type": "object", + "properties": { + "bar": { "$ref": "bar" } + } + }, + "bar": { + "$id": "bar", + "type": "object", + "properties": { + "baz": { "$dynamicRef": "extended#meta" } + } + } + } + }, + "tests": [ + { + "description": "The recursive part doesn't need to validate against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "fail" } + } + }, + "valid": true + } + ] + }, + { + "description": "multiple dynamic paths to the $dynamicRef keyword", + "schema": { + "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main", + "$defs": { + "inner": { + "$id": "inner", + "$dynamicAnchor": "foo", + "title": "inner", + "additionalProperties": { + "$dynamicRef": "#foo" + } + } + }, + "if": { + "propertyNames": { + "pattern": "^[a-m]" + } + }, + "then": { + "title": "any type of node", + "$id": "anyLeafNode", + "$dynamicAnchor": "foo", + "$ref": "inner" + }, + "else": { + "title": "integer node", + "$id": "integerNode", + "$dynamicAnchor": "foo", + "type": [ "object", "integer" ], + "$ref": "inner" + } + }, + "tests": [ + { + "description": "recurse to anyLeafNode - floats are allowed", + "data": { "alpha": 1.1 }, + "valid": true + }, + { + "description": "recurse to integerNode - floats are not allowed", + "data": { "november": 1.1 }, + "valid": false + } + ] + }, + { + "description": "after leaving a dynamic scope, it should not be used by a $dynamicRef", + "schema": { + "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", + "if": { + "$id": "first_scope", + "$defs": { + "thingy": { + "$comment": "this is first_scope#thingy", + "$dynamicAnchor": "thingy", + "type": "number" + } + } + }, + "then": { + "$id": "second_scope", + "$ref": "start", + "$defs": { + "thingy": { + "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", + "$dynamicAnchor": "thingy", + "type": "null" + } + } + }, + "$defs": { + "start": { + "$comment": "this is the landing spot from $ref", + "$id": "start", + "$dynamicRef": "inner_scope#thingy" + }, + "thingy": { + "$comment": "this is the first stop for the $dynamicRef", + "$id": "inner_scope", + "$dynamicAnchor": "thingy", + "type": "string" + } + } + }, + "tests": [ + { + "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here", + "data": "a string", + "valid": false + }, + { + "description": "first_scope is not in dynamic scope for the $dynamicRef", + "data": 42, + "valid": false + }, + { + "description": "/then/$defs/thingy is the final stop for the $dynamicRef", + "data": null, + "valid": true + } + ] + }, + { + "description": "strict-tree schema, guards against misspelled properties", + "schema": { + "$id": "http://localhost:1234/strict-tree.json", + "$dynamicAnchor": "node", + + "$ref": "tree.json", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "instance with misspelled field", + "data": { + "children": [{ + "daat": 1 + }] + }, + "valid": false + }, + { + "description": "instance with correct field", + "data": { + "children": [{ + "data": 1 + }] + }, + "valid": true + } + ] + }, + { + "description": "tests for implementation dynamic anchor and reference link", + "schema": { + "$id": "http://localhost:1234/strict-extendible.json", + "$ref": "extendible-dynamic-ref.json", + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + }, + { + "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.", + "schema": { + "$id": "http://localhost:1234/strict-extendible-allof-defs-first.json", + "allOf": [ + { + "$ref": "extendible-dynamic-ref.json" + }, + { + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + } + ] + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + }, + { + "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.", + "schema": { + "$id": "http://localhost:1234/strict-extendible-allof-ref-first.json", + "allOf": [ + { + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + }, + { + "$ref": "extendible-dynamic-ref.json" + } + ] + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/enum.json python-jsonschema-4.6.0/json/tests/draft2020-12/enum.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/enum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,236 @@ +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"]} + }, + "required": ["bar"] + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + }, + { + "description": "enum with escaped characters", + "schema": { + "enum": ["foo\nbar", "foo\rbar"] + }, + "tests": [ + { + "description": "member 1 is valid", + "data": "foo\nbar", + "valid": true + }, + { + "description": "member 2 is valid", + "data": "foo\rbar", + "valid": true + }, + { + "description": "another string is invalid", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "enum with false does not match 0", + "schema": {"enum": [false]}, + "tests": [ + { + "description": "false is valid", + "data": false, + "valid": true + }, + { + "description": "integer zero is invalid", + "data": 0, + "valid": false + }, + { + "description": "float zero is invalid", + "data": 0.0, + "valid": false + } + ] + }, + { + "description": "enum with true does not match 1", + "schema": {"enum": [true]}, + "tests": [ + { + "description": "true is valid", + "data": true, + "valid": true + }, + { + "description": "integer one is invalid", + "data": 1, + "valid": false + }, + { + "description": "float one is invalid", + "data": 1.0, + "valid": false + } + ] + }, + { + "description": "enum with 0 does not match false", + "schema": {"enum": [0]}, + "tests": [ + { + "description": "false is invalid", + "data": false, + "valid": false + }, + { + "description": "integer zero is valid", + "data": 0, + "valid": true + }, + { + "description": "float zero is valid", + "data": 0.0, + "valid": true + } + ] + }, + { + "description": "enum with 1 does not match true", + "schema": {"enum": [1]}, + "tests": [ + { + "description": "true is invalid", + "data": true, + "valid": false + }, + { + "description": "integer one is valid", + "data": 1, + "valid": true + }, + { + "description": "float one is valid", + "data": 1.0, + "valid": true + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/exclusiveMaximum.json python-jsonschema-4.6.0/json/tests/draft2020-12/exclusiveMaximum.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/exclusiveMaximum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/exclusiveMaximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,30 @@ +[ + { + "description": "exclusiveMaximum validation", + "schema": { + "exclusiveMaximum": 3.0 + }, + "tests": [ + { + "description": "below the exclusiveMaximum is valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + }, + { + "description": "above the exclusiveMaximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/exclusiveMinimum.json python-jsonschema-4.6.0/json/tests/draft2020-12/exclusiveMinimum.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/exclusiveMinimum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/exclusiveMinimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,30 @@ +[ + { + "description": "exclusiveMinimum validation", + "schema": { + "exclusiveMinimum": 1.1 + }, + "tests": [ + { + "description": "above the exclusiveMinimum is valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "below the exclusiveMinimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/format.json python-jsonschema-4.6.0/json/tests/draft2020-12/format.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/format.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,686 @@ +[ + { + "description": "email format", + "schema": { "format": "email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "idn-email format", + "schema": { "format": "idn-email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "regex format", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "ipv4 format", + "schema": { "format": "ipv4" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "ipv6 format", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "idn-hostname format", + "schema": { "format": "idn-hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "hostname format", + "schema": { "format": "hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "date format", + "schema": { "format": "date" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "date-time format", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "time format", + "schema": { "format": "time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "json-pointer format", + "schema": { "format": "json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "relative-json-pointer format", + "schema": { "format": "relative-json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "iri format", + "schema": { "format": "iri" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "iri-reference format", + "schema": { "format": "iri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uri format", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uri-reference format", + "schema": { "format": "uri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uri-template format", + "schema": { "format": "uri-template" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uuid format", + "schema": { "format": "uuid" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "duration format", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/id.json python-jsonschema-4.6.0/json/tests/draft2020-12/id.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,258 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/if-then-else.json python-jsonschema-4.6.0/json/tests/draft2020-12/if-then-else.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/if-then-else.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/if-then-else.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,258 @@ +[ + { + "description": "ignore if without then or else", + "schema": { + "if": { + "const": 0 + } + }, + "tests": [ + { + "description": "valid when valid against lone if", + "data": 0, + "valid": true + }, + { + "description": "valid when invalid against lone if", + "data": "hello", + "valid": true + } + ] + }, + { + "description": "ignore then without if", + "schema": { + "then": { + "const": 0 + } + }, + "tests": [ + { + "description": "valid when valid against lone then", + "data": 0, + "valid": true + }, + { + "description": "valid when invalid against lone then", + "data": "hello", + "valid": true + } + ] + }, + { + "description": "ignore else without if", + "schema": { + "else": { + "const": 0 + } + }, + "tests": [ + { + "description": "valid when valid against lone else", + "data": 0, + "valid": true + }, + { + "description": "valid when invalid against lone else", + "data": "hello", + "valid": true + } + ] + }, + { + "description": "if and then without else", + "schema": { + "if": { + "exclusiveMaximum": 0 + }, + "then": { + "minimum": -10 + } + }, + "tests": [ + { + "description": "valid through then", + "data": -1, + "valid": true + }, + { + "description": "invalid through then", + "data": -100, + "valid": false + }, + { + "description": "valid when if test fails", + "data": 3, + "valid": true + } + ] + }, + { + "description": "if and else without then", + "schema": { + "if": { + "exclusiveMaximum": 0 + }, + "else": { + "multipleOf": 2 + } + }, + "tests": [ + { + "description": "valid when if test passes", + "data": -1, + "valid": true + }, + { + "description": "valid through else", + "data": 4, + "valid": true + }, + { + "description": "invalid through else", + "data": 3, + "valid": false + } + ] + }, + { + "description": "validate against correct branch, then vs else", + "schema": { + "if": { + "exclusiveMaximum": 0 + }, + "then": { + "minimum": -10 + }, + "else": { + "multipleOf": 2 + } + }, + "tests": [ + { + "description": "valid through then", + "data": -1, + "valid": true + }, + { + "description": "invalid through then", + "data": -100, + "valid": false + }, + { + "description": "valid through else", + "data": 4, + "valid": true + }, + { + "description": "invalid through else", + "data": 3, + "valid": false + } + ] + }, + { + "description": "non-interference across combined schemas", + "schema": { + "allOf": [ + { + "if": { + "exclusiveMaximum": 0 + } + }, + { + "then": { + "minimum": -10 + } + }, + { + "else": { + "multipleOf": 2 + } + } + ] + }, + "tests": [ + { + "description": "valid, but would have been invalid through then", + "data": -100, + "valid": true + }, + { + "description": "valid, but would have been invalid through else", + "data": 3, + "valid": true + } + ] + }, + { + "description": "if with boolean schema true", + "schema": { + "if": true, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema true in if always chooses the then path (valid)", + "data": "then", + "valid": true + }, + { + "description": "boolean schema true in if always chooses the then path (invalid)", + "data": "else", + "valid": false + } + ] + }, + { + "description": "if with boolean schema false", + "schema": { + "if": false, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema false in if always chooses the else path (invalid)", + "data": "then", + "valid": false + }, + { + "description": "boolean schema false in if always chooses the else path (valid)", + "data": "else", + "valid": true + } + ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft2020-12/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "$defs": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/$defs/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/$defs/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/items.json python-jsonschema-4.6.0/json/tests/draft2020-12/items.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/items.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/items.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,256 @@ +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + }, + { + "description": "JavaScript pseudo-array is valid", + "data": { + "0": "invalid", + "length": 1 + }, + "valid": true + } + ] + }, + { + "description": "items with boolean schema (true)", + "schema": {"items": true}, + "tests": [ + { + "description": "any array is valid", + "data": [ 1, "foo", true ], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "items with boolean schema (false)", + "schema": {"items": false}, + "tests": [ + { + "description": "any non-empty array is invalid", + "data": [ 1, "foo", true ], + "valid": false + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "items and subitems", + "schema": { + "$defs": { + "item": { + "type": "array", + "items": false, + "prefixItems": [ + { "$ref": "#/$defs/sub-item" }, + { "$ref": "#/$defs/sub-item" } + ] + }, + "sub-item": { + "type": "object", + "required": ["foo"] + } + }, + "type": "array", + "items": false, + "prefixItems": [ + { "$ref": "#/$defs/item" }, + { "$ref": "#/$defs/item" }, + { "$ref": "#/$defs/item" } + ] + }, + "tests": [ + { + "description": "valid items", + "data": [ + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": true + }, + { + "description": "too many items", + "data": [ + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "too many sub-items", + "data": [ + [ {"foo": null}, {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "wrong item", + "data": [ + {"foo": null}, + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "wrong sub-item", + "data": [ + [ {}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "fewer items is valid", + "data": [ + [ {"foo": null} ], + [ {"foo": null} ] + ], + "valid": true + } + ] + }, + { + "description": "nested items", + "schema": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + }, + "tests": [ + { + "description": "valid nested array", + "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], + "valid": true + }, + { + "description": "nested array with invalid type", + "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], + "valid": false + }, + { + "description": "not deep enough", + "data": [[[1], [2],[3]], [[4], [5], [6]]], + "valid": false + } + ] + }, + { + "description": "prefixItems with no additional items allowed", + "schema": { + "prefixItems": [{}, {}, {}], + "items": false + }, + "tests": [ + { + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "equal number of items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "items should not look in applicators, valid case", + "schema": { + "allOf": [ + { "prefixItems": [ { "minimum": 3 } ] } + ], + "items": { "minimum": 5 } + }, + "tests": [ + { + "description": "prefixItems in allOf should not constrain items, invalid case", + "data": [ 3, 5 ], + "valid": false + }, + { + "description": "prefixItems in allOf should not constrain items, valid case", + "data": [ 5, 5 ], + "valid": true + } + ] + }, + { + "description": "prefixItems validation adjusts the starting index for items", + "schema": { + "prefixItems": [ { "type": "string" } ], + "items": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/maxContains.json python-jsonschema-4.6.0/json/tests/draft2020-12/maxContains.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/maxContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/maxContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,79 @@ +[ + { + "description": "maxContains without contains is ignored", + "schema": { + "maxContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "two items still valid against lone maxContains", + "data": [ 1, 2 ], + "valid": true + } + ] + }, + { + "description": "maxContains with contains", + "schema": { + "contains": {"const": 1}, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, valid maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "all elements match, invalid maxContains", + "data": [ 1, 1 ], + "valid": false + }, + { + "description": "some elements match, valid maxContains", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "some elements match, invalid maxContains", + "data": [ 1, 2, 1 ], + "valid": false + } + ] + }, + { + "description": "minContains < maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 1, + "maxContains": 3 + }, + "tests": [ + { + "description": "actual < minContains < maxContains", + "data": [ ], + "valid": false + }, + { + "description": "minContains < actual < maxContains", + "data": [ 1, 1 ], + "valid": true + }, + { + "description": "minContains < maxContains < actual", + "data": [ 1, 1, 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/maximum.json python-jsonschema-4.6.0/json/tests/draft2020-12/maximum.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/maximum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,54 @@ +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "boundary point is valid", + "data": 3.0, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/maxItems.json python-jsonschema-4.6.0/json/tests/draft2020-12/maxItems.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/maxItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/maxItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,28 @@ +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/maxLength.json python-jsonschema-4.6.0/json/tests/draft2020-12/maxLength.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/maxLength.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/maxLength.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,33 @@ +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + }, + { + "description": "two supplementary Unicode code points is long enough", + "data": "\uD83D\uDCA9\uD83D\uDCA9", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/maxProperties.json python-jsonschema-4.6.0/json/tests/draft2020-12/maxProperties.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/maxProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,54 @@ +[ + { + "description": "maxProperties validation", + "schema": {"maxProperties": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "too long is invalid", + "data": {"foo": 1, "bar": 2, "baz": 3}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/minContains.json python-jsonschema-4.6.0/json/tests/draft2020-12/minContains.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/minContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/minContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,197 @@ +[ + { + "description": "minContains without contains is ignored", + "schema": { + "minContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone minContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "zero items still valid against lone minContains", + "data": [], + "valid": true + } + ] + }, + { + "description": "minContains=1 with contains", + "schema": { + "contains": {"const": 1}, + "minContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "no elements match", + "data": [ 2 ], + "valid": false + }, + { + "description": "single element matches, valid minContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "all elements match, valid minContains", + "data": [ 1, 1 ], + "valid": true + } + ] + }, + { + "description": "minContains=2 with contains", + "schema": { + "contains": {"const": 1}, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "some elements match, invalid minContains", + "data": [ 1, 2 ], + "valid": false + }, + { + "description": "all elements match, valid minContains (exactly as needed)", + "data": [ 1, 1 ], + "valid": true + }, + { + "description": "all elements match, valid minContains (more than needed)", + "data": [ 1, 1, 1 ], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [ 1, 2, 1 ], + "valid": true + } + ] + }, + { + "description": "maxContains = minContains", + "schema": { + "contains": {"const": 1}, + "maxContains": 2, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "all elements match, invalid maxContains", + "data": [ 1, 1, 1 ], + "valid": false + }, + { + "description": "all elements match, valid maxContains and minContains", + "data": [ 1, 1 ], + "valid": true + } + ] + }, + { + "description": "maxContains < minContains", + "schema": { + "contains": {"const": 1}, + "maxContains": 1, + "minContains": 3 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "invalid maxContains", + "data": [ 1, 1, 1 ], + "valid": false + }, + { + "description": "invalid maxContains and minContains", + "data": [ 1, 1 ], + "valid": false + } + ] + }, + { + "description": "minContains = 0", + "schema": { + "contains": {"const": 1}, + "minContains": 0 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "minContains = 0 makes contains always pass", + "data": [ 2 ], + "valid": true + } + ] + }, + { + "description": "minContains = 0 with maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 0, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "not more than maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "too many", + "data": [ 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/minimum.json python-jsonschema-4.6.0/json/tests/draft2020-12/minimum.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/minimum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,69 @@ +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "boundary point is valid", + "data": 1.1, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "minimum validation with signed integer", + "schema": {"minimum": -2}, + "tests": [ + { + "description": "negative above the minimum is valid", + "data": -1, + "valid": true + }, + { + "description": "positive above the minimum is valid", + "data": 0, + "valid": true + }, + { + "description": "boundary point is valid", + "data": -2, + "valid": true + }, + { + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", + "data": -3, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/minItems.json python-jsonschema-4.6.0/json/tests/draft2020-12/minItems.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/minItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/minItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,28 @@ +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/minLength.json python-jsonschema-4.6.0/json/tests/draft2020-12/minLength.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/minLength.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/minLength.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,33 @@ +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + }, + { + "description": "one supplementary Unicode code point is not long enough", + "data": "\uD83D\uDCA9", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/minProperties.json python-jsonschema-4.6.0/json/tests/draft2020-12/minProperties.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/minProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/minProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "minProperties validation", + "schema": {"minProperties": 1}, + "tests": [ + { + "description": "longer is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "too short is invalid", + "data": {}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/multipleOf.json python-jsonschema-4.6.0/json/tests/draft2020-12/multipleOf.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/multipleOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,71 @@ +[ + { + "description": "by int", + "schema": {"multipleOf": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"multipleOf": 1.5}, + "tests": [ + { + "description": "zero is multiple of anything", + "data": 0, + "valid": true + }, + { + "description": "4.5 is multiple of 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not multiple of 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"multipleOf": 0.0001}, + "tests": [ + { + "description": "0.0075 is multiple of 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not multiple of 0.0001", + "data": 0.00751, + "valid": false + } + ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/not.json python-jsonschema-4.6.0/json/tests/draft2020-12/not.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/not.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/not.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,117 @@ +[ + { + "description": "not", + "schema": { + "not": {"type": "integer"} + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "not multiple types", + "schema": { + "not": {"type": ["integer", "boolean"]} + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "not more complex schema", + "schema": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + } + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "forbidden property", + "schema": { + "properties": { + "foo": { + "not": {} + } + } + }, + "tests": [ + { + "description": "property present", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "property absent", + "data": {"bar": 1, "baz": 2}, + "valid": true + } + ] + }, + { + "description": "not with boolean schema true", + "schema": {"not": true}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "not with boolean schema false", + "schema": {"not": false}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/oneOf.json python-jsonschema-4.6.0/json/tests/draft2020-12/oneOf.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/oneOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,274 @@ +[ + { + "description": "oneOf", + "schema": { + "oneOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": 1, + "valid": true + }, + { + "description": "second oneOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both oneOf valid", + "data": 3, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "oneOf with base schema", + "schema": { + "type": "string", + "oneOf" : [ + { + "minLength": 2 + }, + { + "maxLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one oneOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both oneOf valid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf with boolean schemas, all true", + "schema": {"oneOf": [true, true, true]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf with boolean schemas, one true", + "schema": {"oneOf": [true, false, false]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "oneOf with boolean schemas, more than one true", + "schema": {"oneOf": [true, true, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf with boolean schemas, all false", + "schema": {"oneOf": [false, false, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf complex types", + "schema": { + "oneOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid (complex)", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "second oneOf valid (complex)", + "data": {"foo": "baz"}, + "valid": true + }, + { + "description": "both oneOf valid (complex)", + "data": {"foo": "baz", "bar": 2}, + "valid": false + }, + { + "description": "neither oneOf valid (complex)", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "oneOf with empty schema", + "schema": { + "oneOf": [ + { "type": "number" }, + {} + ] + }, + "tests": [ + { + "description": "one valid - valid", + "data": "foo", + "valid": true + }, + { + "description": "both valid - invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "oneOf with required", + "schema": { + "type": "object", + "oneOf": [ + { "required": ["foo", "bar"] }, + { "required": ["foo", "baz"] } + ] + }, + "tests": [ + { + "description": "both invalid - invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "first valid - valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "second valid - valid", + "data": {"foo": 1, "baz": 3}, + "valid": true + }, + { + "description": "both valid - invalid", + "data": {"foo": 1, "bar": 2, "baz" : 3}, + "valid": false + } + ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": true, + "baz": true + }, + "required": ["bar"] + }, + { + "properties": { + "foo": true + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/bignum.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/bignum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,93 @@ +[ + { + "description": "integer", + "schema": { "type": "integer" }, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + }, + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": { "type": "number" }, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": { "type": "string" }, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": { "maximum": 18446744073709551615 }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "exclusiveMaximum": 972783798187987123879878123.18878137 + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": { "minimum": -18446744073709551615 }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "exclusiveMinimum": -972783798187987123879878123.18878137 + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/ecmascript-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,552 @@ +[ + { + "description": "ECMA 262 regex $ does not match trailing newline", + "schema": { + "type": "string", + "pattern": "^abc$" + }, + "tests": [ + { + "description": "matches in Python, but should not in jsonschema", + "data": "abc\\n", + "valid": false + }, + { + "description": "should match", + "data": "abc", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex converts \\t to horizontal tab", + "schema": { + "type": "string", + "pattern": "^\\t$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\t", + "valid": false + }, + { + "description": "matches", + "data": "\u0009", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and upper letter", + "schema": { + "type": "string", + "pattern": "^\\cC$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cC", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and lower letter", + "schema": { + "type": "string", + "pattern": "^\\cc$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cc", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\d matches ascii digits only", + "schema": { + "type": "string", + "pattern": "^\\d$" + }, + "tests": [ + { + "description": "ASCII zero matches", + "data": "0", + "valid": true + }, + { + "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", + "data": "߀", + "valid": false + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) does not match", + "data": "\u07c0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\D matches everything but ascii digits", + "schema": { + "type": "string", + "pattern": "^\\D$" + }, + "tests": [ + { + "description": "ASCII zero does not match", + "data": "0", + "valid": false + }, + { + "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", + "data": "߀", + "valid": true + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) matches", + "data": "\u07c0", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\w matches ascii letters only", + "schema": { + "type": "string", + "pattern": "^\\w$" + }, + "tests": [ + { + "description": "ASCII 'a' matches", + "data": "a", + "valid": true + }, + { + "description": "latin-1 e-acute does not match (unlike e.g. Python)", + "data": "é", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\W matches everything but ascii letters", + "schema": { + "type": "string", + "pattern": "^\\W$" + }, + "tests": [ + { + "description": "ASCII 'a' does not match", + "data": "a", + "valid": false + }, + { + "description": "latin-1 e-acute matches (unlike e.g. Python)", + "data": "é", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\s matches whitespace", + "schema": { + "type": "string", + "pattern": "^\\s$" + }, + "tests": [ + { + "description": "ASCII space matches", + "data": " ", + "valid": true + }, + { + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", + "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\S matches everything but whitespace", + "schema": { + "type": "string", + "pattern": "^\\S$" + }, + "tests": [ + { + "description": "ASCII space does not match", + "data": " ", + "valid": false + }, + { + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", + "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/date.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/date.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/date.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/date.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,223 @@ +[ + { + "description": "validation of date strings", + "schema": { "format": "date" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid date string", + "data": "1963-06-19", + "valid": true + }, + { + "description": "a valid date string with 31 days in January", + "data": "2020-01-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in January", + "data": "2020-01-32", + "valid": false + }, + { + "description": "a valid date string with 28 days in February (normal)", + "data": "2021-02-28", + "valid": true + }, + { + "description": "a invalid date string with 29 days in February (normal)", + "data": "2021-02-29", + "valid": false + }, + { + "description": "a valid date string with 29 days in February (leap)", + "data": "2020-02-29", + "valid": true + }, + { + "description": "a invalid date string with 30 days in February (leap)", + "data": "2020-02-30", + "valid": false + }, + { + "description": "a valid date string with 31 days in March", + "data": "2020-03-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in March", + "data": "2020-03-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in April", + "data": "2020-04-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in April", + "data": "2020-04-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in May", + "data": "2020-05-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in May", + "data": "2020-05-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in June", + "data": "2020-06-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in June", + "data": "2020-06-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in July", + "data": "2020-07-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in July", + "data": "2020-07-32", + "valid": false + }, + { + "description": "a valid date string with 31 days in August", + "data": "2020-08-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in August", + "data": "2020-08-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in September", + "data": "2020-09-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in September", + "data": "2020-09-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in October", + "data": "2020-10-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in October", + "data": "2020-10-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in November", + "data": "2020-11-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in November", + "data": "2020-11-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in December", + "data": "2020-12-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in December", + "data": "2020-12-32", + "valid": false + }, + { + "description": "a invalid date string with invalid month", + "data": "2020-13-01", + "valid": false + }, + { + "description": "an invalid date string", + "data": "06/19/1963", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350", + "valid": false + }, + { + "description": "non-padded month dates are not valid", + "data": "1998-1-20", + "valid": false + }, + { + "description": "non-padded day dates are not valid", + "data": "1998-01-1", + "valid": false + }, + { + "description": "invalid month", + "data": "1998-13-01", + "valid": false + }, + { + "description": "invalid month-day combination", + "data": "1998-04-31", + "valid": false + }, + { + "description": "2021 is not a leap year", + "data": "2021-02-29", + "valid": false + }, + { + "description": "2020 is a leap year", + "data": "2020-02-29", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1963-06-1৪", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/date-time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,133 @@ +[ + { + "description": "validation of date-time strings", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "a valid date-time string without second fraction", + "data": "1963-06-19T08:30:06Z", + "valid": true + }, + { + "description": "a valid date-time string with plus offset", + "data": "1937-01-01T12:00:27.87+00:20", + "valid": true + }, + { + "description": "a valid date-time string with minus offset", + "data": "1990-12-31T15:59:50.123-08:00", + "valid": true + }, + { + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", + "valid": false + }, + { + "description": "an invalid offset in date-time string", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", + "valid": false + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "case-insensitive T and Z", + "data": "1963-06-19t08:30:06.283185z", + "valid": true + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/duration.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/duration.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/duration.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/duration.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,128 @@ +[ + { + "description": "validation of duration strings", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid duration string", + "data": "P4DT12H30M5S", + "valid": true + }, + { + "description": "an invalid duration string", + "data": "PT1D", + "valid": false + }, + { + "description": "no elements present", + "data": "P", + "valid": false + }, + { + "description": "no time elements present", + "data": "P1YT", + "valid": false + }, + { + "description": "no date or time elements present", + "data": "PT", + "valid": false + }, + { + "description": "elements out of order", + "data": "P2D1Y", + "valid": false + }, + { + "description": "missing time separator", + "data": "P1D2H", + "valid": false + }, + { + "description": "time element in the date position", + "data": "P2S", + "valid": false + }, + { + "description": "four years duration", + "data": "P4Y", + "valid": true + }, + { + "description": "zero time, in seconds", + "data": "PT0S", + "valid": true + }, + { + "description": "zero time, in days", + "data": "P0D", + "valid": true + }, + { + "description": "one month duration", + "data": "P1M", + "valid": true + }, + { + "description": "one minute duration", + "data": "PT1M", + "valid": true + }, + { + "description": "one and a half days, in hours", + "data": "PT36H", + "valid": true + }, + { + "description": "one and a half days, in days and hours", + "data": "P1DT12H", + "valid": true + }, + { + "description": "two weeks", + "data": "P2W", + "valid": true + }, + { + "description": "weeks cannot be combined with other units", + "data": "P1Y2W", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "P২Y", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,118 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": { "format": "email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "a quoted string with a space in the local part is valid", + "data": "\"joe bloggs\"@example.com", + "valid": true + }, + { + "description": "a quoted string with a double dot in the local part is valid", + "data": "\"joe..bloggs\"@example.com", + "valid": true + }, + { + "description": "a quoted string with a @ in the local part is valid", + "data": "\"joe@bloggs\"@example.com", + "valid": true + }, + { + "description": "an IPv4-address-literal after the @ is valid", + "data": "joe.bloggs@[127.0.0.1]", + "valid": true + }, + { + "description": "an IPv6-address-literal after the @ is valid", + "data": "joe.bloggs@[IPv6:::1]", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false + }, + { + "description": "an invalid domain", + "data": "joe.bloggs@invalid=domain.com", + "valid": false + }, + { + "description": "an invalid IPv4-address-literal", + "data": "joe.bloggs@[127.0.0.300]", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/hostname.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,98 @@ +[ + { + "description": "validation of host names", + "schema": { "format": "hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a valid punycoded IDN hostname", + "data": "xn--4gbwdl.xn--wgbh1c", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/idn-email.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/idn-email.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/idn-email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/idn-email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,58 @@ +[ + { + "description": "validation of an internationalized e-mail addresses", + "schema": { "format": "idn-email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid idn e-mail (example@example.test in Hangul)", + "data": "실례@실례.테스트", + "valid": true + }, + { + "description": "an invalid idn e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/idn-hostname.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/idn-hostname.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/idn-hostname.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/idn-hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,304 @@ +[ + { + "description": "validation of internationalized host names", + "schema": { "format": "idn-hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid host name (example.test in Hangul)", + "data": "실례.테스트", + "valid": true + }, + { + "description": "illegal first char U+302E Hangul single dot tone mark", + "data": "〮실례.테스트", + "valid": false + }, + { + "description": "contains illegal char U+302E Hangul single dot tone mark", + "data": "실〮례.테스트", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", + "valid": false + }, + { + "description": "invalid label, correct Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", + "data": "-> $1.00 <--", + "valid": false + }, + { + "description": "valid Chinese Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", + "data": "xn--ihqwcrb4cv8a8dqg056pqjye", + "valid": true + }, + { + "description": "invalid Punycode", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "xn--X", + "valid": false + }, + { + "description": "U-label contains \"--\" in the 3rd and 4th position", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "XN--aa---o47jg78q", + "valid": false + }, + { + "description": "U-label starts with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello", + "valid": false + }, + { + "description": "U-label ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "hello-", + "valid": false + }, + { + "description": "U-label starts and ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello-", + "valid": false + }, + { + "description": "Begins with a Spacing Combining Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0903hello", + "valid": false + }, + { + "description": "Begins with a Nonspacing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0300hello", + "valid": false + }, + { + "description": "Begins with an Enclosing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0488hello", + "valid": false + }, + { + "description": "Exceptions that are PVALID, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u00df\u03c2\u0f0b\u3007", + "valid": true + }, + { + "description": "Exceptions that are PVALID, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u06fd\u06fe", + "valid": true + }, + { + "description": "Exceptions that are DISALLOWED, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u0640\u07fa", + "valid": false + }, + { + "description": "Exceptions that are DISALLOWED, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", + "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", + "valid": false + }, + { + "description": "MIDDLE DOT with no preceding 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "a\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing preceding", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with no following 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7a", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing following", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7", + "valid": false + }, + { + "description": "MIDDLE DOT with surrounding 'l's", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7l", + "valid": true + }, + { + "description": "Greek KERAIA not followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375S", + "valid": false + }, + { + "description": "Greek KERAIA not followed by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375", + "valid": false + }, + { + "description": "Greek KERAIA followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375\u03b2", + "valid": true + }, + { + "description": "Hebrew GERESH not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "A\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05d0\u05f3\u05d1", + "valid": true + }, + { + "description": "Hebrew GERSHAYIM not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "A\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05d0\u05f4\u05d1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "def\u30fbabc", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with no other characters", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with Hiragana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u3041", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Katakana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u30a1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u4e08", + "valid": true + }, + { + "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0660\u06f0", + "valid": false + }, + { + "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0628\u0660\u0628", + "valid": true + }, + { + "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", + "data": "\u06f00", + "valid": true + }, + { + "description": "ZERO WIDTH JOINER not preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u094d\u200d\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", + "data": "\u0915\u094d\u200c\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", + "data": "\u0628\u064a\u200c\u0628\u064a", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/ipv4.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,84 @@ +[ + { + "description": "validation of IP addresses", + "schema": { "format": "ipv4" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/ipv6.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,208 @@ +[ + { + "description": "validation of IPv6 addresses", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/iri.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/iri.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/iri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/iri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,83 @@ +[ + { + "description": "validation of IRIs", + "schema": { "format": "iri" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IRI with anchor tag", + "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", + "valid": true + }, + { + "description": "a valid IRI with anchor tag and parentheses", + "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", + "valid": true + }, + { + "description": "a valid IRI with URL-encoded stuff", + "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", + "valid": true + }, + { + "description": "a valid IRI with many special characters", + "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", + "valid": true + }, + { + "description": "a valid IRI based on IPv6", + "data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", + "valid": true + }, + { + "description": "an invalid IRI based on IPv6", + "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "valid": false + }, + { + "description": "an invalid relative IRI Reference", + "data": "/abc", + "valid": false + }, + { + "description": "an invalid IRI", + "data": "\\\\WINDOWS\\filëßåré", + "valid": false + }, + { + "description": "an invalid IRI though valid IRI reference", + "data": "âππ", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/iri-reference.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/iri-reference.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/iri-reference.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/iri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,73 @@ +[ + { + "description": "validation of IRI References", + "schema": { "format": "iri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IRI", + "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", + "valid": true + }, + { + "description": "a valid protocol-relative IRI Reference", + "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", + "valid": true + }, + { + "description": "a valid relative IRI Reference", + "data": "/âππ", + "valid": true + }, + { + "description": "an invalid IRI Reference", + "data": "\\\\WINDOWS\\filëßåré", + "valid": false + }, + { + "description": "a valid IRI Reference", + "data": "âππ", + "valid": true + }, + { + "description": "a valid IRI fragment", + "data": "#ƒrägmênt", + "valid": true + }, + { + "description": "an invalid IRI fragment", + "data": "#ƒräg\\mênt", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/json-pointer.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/json-pointer.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,198 @@ +[ + { + "description": "validation of JSON-pointers (JSON String Representation)", + "schema": { "format": "json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid JSON-pointer", + "data": "/foo/bar~0/baz~1/%a", + "valid": true + }, + { + "description": "not a valid JSON-pointer (~ not escaped)", + "data": "/foo/bar~", + "valid": false + }, + { + "description": "valid JSON-pointer with empty segment", + "data": "/foo//bar", + "valid": true + }, + { + "description": "valid JSON-pointer with the last empty segment", + "data": "/foo/bar/", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #1", + "data": "", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #2", + "data": "/foo", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #3", + "data": "/foo/0", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #4", + "data": "/", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #5", + "data": "/a~1b", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #6", + "data": "/c%d", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #7", + "data": "/e^f", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #8", + "data": "/g|h", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #9", + "data": "/i\\j", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #10", + "data": "/k\"l", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #11", + "data": "/ ", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #12", + "data": "/m~0n", + "valid": true + }, + { + "description": "valid JSON-pointer used adding to the last array position", + "data": "/foo/-", + "valid": true + }, + { + "description": "valid JSON-pointer (- used as object member name)", + "data": "/foo/-/bar", + "valid": true + }, + { + "description": "valid JSON-pointer (multiple escaped characters)", + "data": "/~1~0~0~1~1", + "valid": true + }, + { + "description": "valid JSON-pointer (escaped with fraction part) #1", + "data": "/~1.1", + "valid": true + }, + { + "description": "valid JSON-pointer (escaped with fraction part) #2", + "data": "/~0.1", + "valid": true + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", + "data": "#", + "valid": false + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", + "data": "#/", + "valid": false + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", + "data": "#a", + "valid": false + }, + { + "description": "not a valid JSON-pointer (some escaped, but not all) #1", + "data": "/~0~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (some escaped, but not all) #2", + "data": "/~0/~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (wrong escape character) #1", + "data": "/~2", + "valid": false + }, + { + "description": "not a valid JSON-pointer (wrong escape character) #2", + "data": "/~-1", + "valid": false + }, + { + "description": "not a valid JSON-pointer (multiple characters not escaped)", + "data": "/~~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", + "data": "a", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", + "data": "0", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", + "data": "a/a", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/regex.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/regex.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,48 @@ +[ + { + "description": "validation of regular expressions", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid regular expression", + "data": "([abc])+\\s+$", + "valid": true + }, + { + "description": "a regular expression with unclosed parens is invalid", + "data": "^(abc]", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/relative-json-pointer.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/relative-json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/relative-json-pointer.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/relative-json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,83 @@ +[ + { + "description": "validation of Relative JSON Pointers (RJP)", + "schema": { "format": "relative-json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid upwards RJP", + "data": "1", + "valid": true + }, + { + "description": "a valid downwards RJP", + "data": "0/foo/bar", + "valid": true + }, + { + "description": "a valid up and then down RJP, with array index", + "data": "2/0/baz/1/zip", + "valid": true + }, + { + "description": "a valid RJP taking the member or index name", + "data": "0#", + "valid": true + }, + { + "description": "an invalid RJP that is a valid JSON Pointer", + "data": "/foo/bar", + "valid": false + }, + { + "description": "negative prefix", + "data": "-1/foo/bar", + "valid": false + }, + { + "description": "## is not a valid json-pointer", + "data": "0##", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus json-pointer", + "data": "01/a", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus octothorpe", + "data": "01#", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/time.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/time.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,198 @@ +[ + { + "description": "validation of time strings", + "schema": { "format": "time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid time string", + "data": "08:30:06Z", + "valid": true + }, + { + "description": "a valid time string with leap second, Zulu", + "data": "23:59:60Z", + "valid": true + }, + { + "description": "invalid leap second, Zulu (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "invalid leap second, Zulu (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "valid leap second, zero time-offset", + "data": "23:59:60+00:00", + "valid": true + }, + { + "description": "invalid leap second, zero time-offset (wrong hour)", + "data": "22:59:60+00:00", + "valid": false + }, + { + "description": "invalid leap second, zero time-offset (wrong minute)", + "data": "23:58:60+00:00", + "valid": false + }, + { + "description": "valid leap second, positive time-offset", + "data": "01:29:60+01:30", + "valid": true + }, + { + "description": "valid leap second, large positive time-offset", + "data": "23:29:60+23:30", + "valid": true + }, + { + "description": "invalid leap second, positive time-offset (wrong hour)", + "data": "23:59:60+01:00", + "valid": false + }, + { + "description": "invalid leap second, positive time-offset (wrong minute)", + "data": "23:59:60+00:30", + "valid": false + }, + { + "description": "valid leap second, negative time-offset", + "data": "15:59:60-08:00", + "valid": true + }, + { + "description": "valid leap second, large negative time-offset", + "data": "00:29:60-23:30", + "valid": true + }, + { + "description": "invalid leap second, negative time-offset (wrong hour)", + "data": "23:59:60-01:00", + "valid": false + }, + { + "description": "invalid leap second, negative time-offset (wrong minute)", + "data": "23:59:60-00:30", + "valid": false + }, + { + "description": "a valid time string with second fraction", + "data": "23:20:50.52Z", + "valid": true + }, + { + "description": "a valid time string with precise second fraction", + "data": "08:30:06.283185Z", + "valid": true + }, + { + "description": "a valid time string with plus offset", + "data": "08:30:06+00:20", + "valid": true + }, + { + "description": "a valid time string with minus offset", + "data": "08:30:06-08:00", + "valid": true + }, + { + "description": "a valid time string with case-insensitive Z", + "data": "08:30:06z", + "valid": true + }, + { + "description": "an invalid time string with invalid hour", + "data": "24:00:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid minute", + "data": "00:60:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid second", + "data": "00:00:61Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset hour", + "data": "01:02:03+24:00", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset minute", + "data": "01:02:03+00:60", + "valid": false + }, + { + "description": "an invalid time string with invalid time with both Z and numoffset", + "data": "01:02:03Z+00:30", + "valid": false + }, + { + "description": "an invalid offset indicator", + "data": "08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "01:01:01,1111", + "valid": false + }, + { + "description": "no time offset", + "data": "12:00:00", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২:00:00Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/unknown.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/unknown.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/unknown.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/unknown.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,43 @@ +[ + { + "description": "unknown format", + "schema": { "format": "unknown" }, + "tests": [ + { + "description": "unknown formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "unknown formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "unknown formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "unknown formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "unknown formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "unknown formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "unknown formats ignore strings", + "data": "string", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,108 @@ +[ + { + "description": "validation of URIs", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "a valid URL with anchor tag", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid URL with anchor tag and parentheses", + "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", + "valid": true + }, + { + "description": "a valid URL with URL-encoded stuff", + "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", + "valid": true + }, + { + "description": "a valid puny-coded URL ", + "data": "http://xn--nw2a.xn--j6w193g/", + "valid": true + }, + { + "description": "a valid URL with many special characters", + "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", + "valid": true + }, + { + "description": "a valid URL based on IPv4", + "data": "http://223.255.255.254", + "valid": true + }, + { + "description": "a valid URL with ftp scheme", + "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", + "valid": true + }, + { + "description": "a valid URL for a simple text file", + "data": "http://www.ietf.org/rfc/rfc2396.txt", + "valid": true + }, + { + "description": "a valid URL ", + "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", + "valid": true + }, + { + "description": "a valid mailto URI", + "data": "mailto:John.Doe@example.com", + "valid": true + }, + { + "description": "a valid newsgroup URI", + "data": "news:comp.infosystems.www.servers.unix", + "valid": true + }, + { + "description": "a valid tel URI", + "data": "tel:+1-816-555-1212", + "valid": true + }, + { + "description": "a valid URN", + "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", + "valid": true + }, + { + "description": "an invalid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": false + }, + { + "description": "an invalid relative URI Reference", + "data": "/abc", + "valid": false + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + }, + { + "description": "an invalid URI with spaces", + "data": "http:// shouldfail.com", + "valid": false + }, + { + "description": "an invalid URI with spaces and missing scheme", + "data": ":// should fail", + "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uri-reference.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uri-reference.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uri-reference.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,73 @@ +[ + { + "description": "validation of URI References", + "schema": { "format": "uri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid relative URI Reference", + "data": "/abc", + "valid": true + }, + { + "description": "an invalid URI Reference", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "a valid URI Reference", + "data": "abc", + "valid": true + }, + { + "description": "a valid URI fragment", + "data": "#fragment", + "valid": true + }, + { + "description": "an invalid URI fragment", + "data": "#frag\\ment", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uri-template.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uri-template.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uri-template.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uri-template.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,58 @@ +[ + { + "description": "format: uri-template", + "schema": { "format": "uri-template" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid uri-template", + "data": "http://example.com/dictionary/{term:1}/{term}", + "valid": true + }, + { + "description": "an invalid uri-template", + "data": "http://example.com/dictionary/{term:1}/{term", + "valid": false + }, + { + "description": "a valid uri-template without variables", + "data": "http://example.com/dictionary", + "valid": true + }, + { + "description": "a valid relative uri-template", + "data": "dictionary/{term:1}/{term}", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uuid.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uuid.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format/uuid.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format/uuid.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,85 @@ +[ + { + "description": "uuid format", + "schema": { + "format": "uuid" + }, + "tests": [ + { + "description": "all upper-case", + "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", + "valid": true + }, + { + "description": "all lower-case", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", + "valid": true + }, + { + "description": "mixed case", + "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", + "valid": true + }, + { + "description": "all zeroes is valid", + "data": "00000000-0000-0000-0000-000000000000", + "valid": true + }, + { + "description": "wrong length", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": false + }, + { + "description": "missing section", + "data": "2eb8aa08-aa98-11ea-73b441d16380", + "valid": false + }, + { + "description": "bad characters (not hex)", + "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", + "valid": false + }, + { + "description": "no dashes", + "data": "2eb8aa08aa9811eab4aa73b441d16380", + "valid": false + }, + { + "description": "too few dashes", + "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", + "valid": false + }, + { + "description": "too many dashes", + "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", + "valid": false + }, + { + "description": "dashes in the wrong spot", + "data": "2eb8aa08aa9811eab4aa73b441d16380----", + "valid": false + }, + { + "description": "valid version 4", + "data": "98d80576-482e-427f-8434-7f86890ab222", + "valid": true + }, + { + "description": "valid version 5", + "data": "99c17cbb-656f-564a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 6", + "data": "99c17cbb-656f-664a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 15", + "data": "99c17cbb-656f-f64a-940f-1a4568f03487", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format-assertion.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format-assertion.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/format-assertion.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/format-assertion.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,42 @@ +[ + { + "description": "schema that uses custom metaschema with format-assertion: false", + "schema": { + "$id": "https://schema/using/format-assertion/false", + "$schema": "http://localhost:1234/draft2020-12/format-assertion-false.json", + "format": "ipv4" + }, + "tests": [ + { + "description": "format-assertion: false: valid string", + "data": "127.0.0.1", + "valid": true + }, + { + "description": "format-assertion: false: invalid string", + "data": "not-an-ipv4", + "valid": false + } + ] + }, + { + "description": "schema that uses custom metaschema with format-assertion: true", + "schema": { + "$id": "https://schema/using/format-assertion/true", + "$schema": "http://localhost:1234/draft2020-12/format-assertion-true.json", + "format": "ipv4" + }, + "tests": [ + { + "description": "format-assertion: true: valid string", + "data": "127.0.0.1", + "valid": true + }, + { + "description": "format-assertion: true: invalid string", + "data": "not-an-ipv4", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/optional/refOfUnknownKeyword.json python-jsonschema-4.6.0/json/tests/draft2020-12/optional/refOfUnknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/optional/refOfUnknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/optional/refOfUnknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,44 @@ +[ + { + "description": "reference of a root arbitrary keyword ", + "schema": { + "unknown-keyword": {"type": "integer"}, + "properties": { + "bar": {"$ref": "#/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "reference of an arbitrary keyword of a sub-schema", + "schema": { + "properties": { + "foo": {"unknown-keyword": {"type": "integer"}}, + "bar": {"$ref": "#/properties/foo/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/pattern.json python-jsonschema-4.6.0/json/tests/draft2020-12/pattern.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/pattern.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,59 @@ +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "pattern is not anchored", + "schema": {"pattern": "a+"}, + "tests": [ + { + "description": "matches a substring", + "data": "xxaayy", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/patternProperties.json python-jsonschema-4.6.0/json/tests/draft2020-12/patternProperties.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/patternProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/patternProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,156 @@ +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["foo"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + }, + { + "description": "patternProperties with boolean schemas", + "schema": { + "patternProperties": { + "f.*": true, + "b.*": false + } + }, + "tests": [ + { + "description": "object with property matching schema true is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property matching schema false is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "object with both properties is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "object with a property matching both true and false is invalid", + "data": {"foobar":1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/prefixItems.json python-jsonschema-4.6.0/json/tests/draft2020-12/prefixItems.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/prefixItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/prefixItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,81 @@ +[ + { + "description": "a schema given for prefixItems", + "schema": { + "prefixItems": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + }, + { + "description": "incomplete array of items", + "data": [ 1 ], + "valid": true + }, + { + "description": "array with additional items", + "data": [ 1, "foo", true ], + "valid": true + }, + { + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "JavaScript pseudo-array is valid", + "data": { + "0": "invalid", + "1": "valid", + "length": 2 + }, + "valid": true + } + ] + }, + { + "description": "prefixItems with boolean schemas", + "schema": { + "prefixItems": [true, false] + }, + "tests": [ + { + "description": "array with one item is valid", + "data": [ 1 ], + "valid": true + }, + { + "description": "array with two items is invalid", + "data": [ 1, "foo" ], + "valid": false + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "additional items are allowed by default", + "schema": {"prefixItems": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/properties.json python-jsonschema-4.6.0/json/tests/draft2020-12/properties.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/properties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/properties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,167 @@ +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + }, + { + "description": "properties with boolean schema", + "schema": { + "properties": { + "foo": true, + "bar": false + } + }, + "tests": [ + { + "description": "no property present is valid", + "data": {}, + "valid": true + }, + { + "description": "only 'true' property present is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "only 'false' property present is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "both properties present is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + } + ] + }, + { + "description": "properties with escaped characters", + "schema": { + "properties": { + "foo\nbar": {"type": "number"}, + "foo\"bar": {"type": "number"}, + "foo\\bar": {"type": "number"}, + "foo\rbar": {"type": "number"}, + "foo\tbar": {"type": "number"}, + "foo\fbar": {"type": "number"} + } + }, + "tests": [ + { + "description": "object with all numbers is valid", + "data": { + "foo\nbar": 1, + "foo\"bar": 1, + "foo\\bar": 1, + "foo\rbar": 1, + "foo\tbar": 1, + "foo\fbar": 1 + }, + "valid": true + }, + { + "description": "object with strings is invalid", + "data": { + "foo\nbar": "1", + "foo\"bar": "1", + "foo\\bar": "1", + "foo\rbar": "1", + "foo\tbar": "1", + "foo\fbar": "1" + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/propertyNames.json python-jsonschema-4.6.0/json/tests/draft2020-12/propertyNames.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/propertyNames.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/propertyNames.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,78 @@ +[ + { + "description": "propertyNames validation", + "schema": { + "propertyNames": {"maxLength": 3} + }, + "tests": [ + { + "description": "all property names valid", + "data": { + "f": {}, + "foo": {} + }, + "valid": true + }, + { + "description": "some property names invalid", + "data": { + "foo": {}, + "foobar": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [1, 2, 3, 4], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "propertyNames with boolean schema true", + "schema": {"propertyNames": true}, + "tests": [ + { + "description": "object with any properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with boolean schema false", + "schema": {"propertyNames": false}, + "tests": [ + { + "description": "object with any properties is invalid", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/ref.json python-jsonschema-4.6.0/json/tests/draft2020-12/ref.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/ref.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,581 @@ +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "prefixItems": [ + {"type": "integer"}, + {"$ref": "#/prefixItems/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "$defs": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, + "properties": { + "tilde": {"$ref": "#/$defs/tilde~0field"}, + "slash": {"$ref": "#/$defs/slash~1field"}, + "percent": {"$ref": "#/$defs/percent%25field"} + } + }, + "tests": [ + { + "description": "slash invalid", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, + "valid": false + }, + { + "description": "percent invalid", + "data": {"percent": "aoeu"}, + "valid": false + }, + { + "description": "slash valid", + "data": {"slash": 123}, + "valid": true + }, + { + "description": "tilde valid", + "data": {"tilde": 123}, + "valid": true + }, + { + "description": "percent valid", + "data": {"percent": 123}, + "valid": true + } + ] + }, + { + "description": "nested refs", + "schema": { + "$defs": { + "a": {"type": "integer"}, + "b": {"$ref": "#/$defs/a"}, + "c": {"$ref": "#/$defs/b"} + }, + "$ref": "#/$defs/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref applies alongside sibling keywords", + "schema": { + "$defs": { + "reffed": { + "type": "array" + } + }, + "properties": { + "foo": { + "$ref": "#/$defs/reffed", + "maxItems": 2 + } + } + }, + "tests": [ + { + "description": "ref valid, maxItems valid", + "data": { "foo": [] }, + "valid": true + }, + { + "description": "ref valid, maxItems invalid", + "data": { "foo": [1, 2, 3] }, + "valid": false + }, + { + "description": "ref invalid", + "data": { "foo": "string" }, + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "remote ref valid", + "data": {"minLength": 1}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"minLength": -1}, + "valid": false + } + ] + }, + { + "description": "property named $ref that is not a reference", + "schema": { + "properties": { + "$ref": {"type": "string"} + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/$defs/is-string"} + }, + "$defs": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { + "description": "$ref to boolean schema true", + "schema": { + "$ref": "#/$defs/bool", + "$defs": { + "bool": true + } + }, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "$ref to boolean schema false", + "schema": { + "$ref": "#/$defs/bool", + "$defs": { + "bool": false + } + }, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "Recursive references between schemas", + "schema": { + "$id": "http://localhost:1234/tree", + "description": "tree of nodes", + "type": "object", + "properties": { + "meta": {"type": "string"}, + "nodes": { + "type": "array", + "items": {"$ref": "node"} + } + }, + "required": ["meta", "nodes"], + "$defs": { + "node": { + "$id": "http://localhost:1234/node", + "description": "node", + "type": "object", + "properties": { + "value": {"type": "number"}, + "subtree": {"$ref": "tree"} + }, + "required": ["value"] + } + } + }, + "tests": [ + { + "description": "valid tree", + "data": { + "meta": "root", + "nodes": [ + { + "value": 1, + "subtree": { + "meta": "child", + "nodes": [ + {"value": 1.1}, + {"value": 1.2} + ] + } + }, + { + "value": 2, + "subtree": { + "meta": "child", + "nodes": [ + {"value": 2.1}, + {"value": 2.2} + ] + } + } + ] + }, + "valid": true + }, + { + "description": "invalid tree", + "data": { + "meta": "root", + "nodes": [ + { + "value": 1, + "subtree": { + "meta": "child", + "nodes": [ + {"value": "string is invalid"}, + {"value": 1.2} + ] + } + }, + { + "value": 2, + "subtree": { + "meta": "child", + "nodes": [ + {"value": 2.1}, + {"value": 2.2} + ] + } + } + ] + }, + "valid": false + } + ] + }, + { + "description": "refs with quote", + "schema": { + "properties": { + "foo\"bar": {"$ref": "#/$defs/foo%22bar"} + }, + "$defs": { + "foo\"bar": {"type": "number"} + } + }, + "tests": [ + { + "description": "object with numbers is valid", + "data": { + "foo\"bar": 1 + }, + "valid": true + }, + { + "description": "object with strings is invalid", + "data": { + "foo\"bar": "1" + }, + "valid": false + } + ] + }, + { + "description": "ref creates new scope when adjacent to keywords", + "schema": { + "$defs": { + "A": { + "unevaluatedProperties": false + } + }, + "properties": { + "prop1": { + "type": "string" + } + }, + "$ref": "#/$defs/A" + }, + "tests": [ + { + "description": "referenced subschema doesn't see annotations from properties", + "data": { + "prop1": "match" + }, + "valid": false + } + ] + }, + { + "description": "naive replacement of $ref with its destination is not correct", + "schema": { + "$defs": { + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/$defs/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "do not evaluate the $ref inside the enum, definition exact match", + "data": { "type": "string" }, + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/$defs/a_string" }, + "valid": true + } + ] + }, + { + "description": "refs with relative uris and defs", + "schema": { + "$id": "http://example.com/schema-relative-uri-defs1.json", + "properties": { + "foo": { + "$id": "schema-relative-uri-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-relative-uri-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "relative refs with absolute uris and defs", + "schema": { + "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", + "properties": { + "foo": { + "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-refs-absolute-uris-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "$id must be resolved against nearest parent, not just immediate parent", + "schema": { + "$id": "http://example.com/a.json", + "$defs": { + "x": { + "$id": "http://example.com/b/c.json", + "not": { + "$defs": { + "y": { + "$id": "d.json", + "type": "number" + } + } + } + } + }, + "allOf": [ + { + "$ref": "http://example.com/b/d.json" + } + ] + }, + "tests": [ + { + "description": "number should pass", + "data": 1, + "valid": true + }, + { + "description": "non-number should fail", + "data": "a", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/refRemote.json python-jsonschema-4.6.0/json/tests/draft2020-12/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/refRemote.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,190 @@ +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "base URI change", + "schema": { + "$id": "http://localhost:1234/", + "items": { + "$id": "baseUriChange/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "base URI change ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "base URI change ref invalid", + "data": [["a"]], + "valid": false + } + ] + }, + { + "description": "base URI change - change folder", + "schema": { + "$id": "http://localhost:1234/scope_change_defs1.json", + "type" : "object", + "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, + "$defs": { + "baz": { + "$id": "baseUriChangeFolder/", + "type": "array", + "items": {"$ref": "folderInteger.json"} + } + } + }, + "tests": [ + { + "description": "number is valid", + "data": {"list": [1]}, + "valid": true + }, + { + "description": "string is invalid", + "data": {"list": ["a"]}, + "valid": false + } + ] + }, + { + "description": "base URI change - change folder in subschema", + "schema": { + "$id": "http://localhost:1234/scope_change_defs2.json", + "type" : "object", + "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, + "$defs": { + "baz": { + "$id": "baseUriChangeFolderInSubschema/", + "$defs": { + "bar": { + "type": "array", + "items": {"$ref": "folderInteger.json"} + } + } + } + } + }, + "tests": [ + { + "description": "number is valid", + "data": {"list": [1]}, + "valid": true + }, + { + "description": "string is invalid", + "data": {"list": ["a"]}, + "valid": false + } + ] + }, + { + "description": "root ref in remote ref", + "schema": { + "$id": "http://localhost:1234/object", + "type": "object", + "properties": { + "name": {"$ref": "name-defs.json#/$defs/orNull"} + } + }, + "tests": [ + { + "description": "string is valid", + "data": { + "name": "foo" + }, + "valid": true + }, + { + "description": "null is valid", + "data": { + "name": null + }, + "valid": true + }, + { + "description": "object is invalid", + "data": { + "name": { + "name": null + } + }, + "valid": false + } + ] + }, + { + "description": "remote ref with ref to defs", + "schema": { + "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", + "$ref": "ref-and-defs.json" + }, + "tests": [ + { + "description": "invalid", + "data": { + "bar": 1 + }, + "valid": false + }, + { + "description": "valid", + "data": { + "bar": "a" + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/required.json python-jsonschema-4.6.0/json/tests/draft2020-12/required.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/required.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/required.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,105 @@ +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": ["foo"] + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + }, + { + "description": "required with empty array", + "schema": { + "properties": { + "foo": {} + }, + "required": [] + }, + "tests": [ + { + "description": "property not required", + "data": {}, + "valid": true + } + ] + }, + { + "description": "required with escaped characters", + "schema": { + "required": [ + "foo\nbar", + "foo\"bar", + "foo\\bar", + "foo\rbar", + "foo\tbar", + "foo\fbar" + ] + }, + "tests": [ + { + "description": "object with all properties present is valid", + "data": { + "foo\nbar": 1, + "foo\"bar": 1, + "foo\\bar": 1, + "foo\rbar": 1, + "foo\tbar": 1, + "foo\fbar": 1 + }, + "valid": true + }, + { + "description": "object with some properties missing is invalid", + "data": { + "foo\nbar": "1", + "foo\"bar": "1" + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/type.json python-jsonschema-4.6.0/json/tests/draft2020-12/type.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/type.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,474 @@ +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float with zero fractional part is an integer", + "data": 1.0, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "a string is still not an integer, even if it looks like one", + "data": "1", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float with zero fractional part is a number (and an integer)", + "data": 1.0, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "a string is still not a number, even if it looks like one", + "data": "1", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "a string is still a string, even if it looks like a number", + "data": "1", + "valid": true + }, + { + "description": "an empty string is still a string", + "data": "", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "zero is not a boolean", + "data": 0, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an empty string is not a boolean", + "data": "", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "true is a boolean", + "data": true, + "valid": true + }, + { + "description": "false is a boolean", + "data": false, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "zero is not null", + "data": 0, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an empty string is not null", + "data": "", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "true is not null", + "data": true, + "valid": false + }, + { + "description": "false is not null", + "data": false, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": "type as array with one item", + "schema": { + "type": ["string"] + }, + "tests": [ + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "number is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "type: array or object", + "schema": { + "type": ["array", "object"] + }, + "tests": [ + { + "description": "array is valid", + "data": [1,2,3], + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": 123}, + "valid": true + }, + { + "description": "number is invalid", + "data": 123, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": "type: array, object or null", + "schema": { + "type": ["array", "object", "null"] + }, + "tests": [ + { + "description": "array is valid", + "data": [1,2,3], + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": 123}, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is invalid", + "data": 123, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/unevaluatedItems.json python-jsonschema-4.6.0/json/tests/draft2020-12/unevaluatedItems.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/unevaluatedItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/unevaluatedItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,633 @@ +[ + { + "description": "unevaluatedItems true", + "schema": { + "type": "array", + "unevaluatedItems": true + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems false", + "schema": { + "type": "array", + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems as schema", + "schema": { + "type": "array", + "unevaluatedItems": { "type": "string" } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with valid unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with invalid unevaluated items", + "data": [42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with uniform items", + "schema": { + "type": "array", + "items": { "type": "string" }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", "bar"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with tuple", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with items", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "items": true, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested tuple", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "allOf": [ + { + "prefixItems": [ + true, + { "type": "number" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", 42], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", 42, true], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with nested items", + "schema": { + "type": "array", + "allOf": [ + { + "prefixItems": [ + { "type": "string" } + ], + "items": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested unevaluatedItems", + "schema": { + "type": "array", + "allOf": [ + { + "prefixItems": [ + { "type": "string" } + ] + }, + { + "unevaluatedItems": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with anyOf", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "anyOf": [ + { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + { + "prefixItems": [ + true, + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when one schema matches and has no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "when one schema matches and has unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + }, + { + "description": "when two schemas match and has no unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "when two schemas match and has unevaluated items", + "data": ["foo", "bar", "baz", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with oneOf", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "oneOf": [ + { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + { + "prefixItems": [ + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with not", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "not": { + "not": { + "prefixItems": [ + true, + { "const": "bar" } + ] + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with if/then/else", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "if": { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + "then": { + "prefixItems": [ + true, + true, + { "const": "then" } + ] + }, + "else": { + "prefixItems": [ + true, + true, + true, + { "const": "else" } + ] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when if matches and it has no unevaluated items", + "data": ["foo", "bar", "then"], + "valid": true + }, + { + "description": "when if matches and it has unevaluated items", + "data": ["foo", "bar", "then", "else"], + "valid": false + }, + { + "description": "when if doesn't match and it has no unevaluated items", + "data": ["foo", 42, 42, "else"], + "valid": true + }, + { + "description": "when if doesn't match and it has unevaluated items", + "data": ["foo", 42, 42, "else", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with boolean schemas", + "schema": { + "type": "array", + "allOf": [true], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $ref", + "schema": { + "type": "array", + "$ref": "#/$defs/bar", + "prefixItems": [ + { "type": "string" } + ], + "unevaluatedItems": false, + "$defs": { + "bar": { + "prefixItems": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems can't see inside cousins", + "schema": { + "allOf": [ + { + "prefixItems": [ true ] + }, + { + "unevaluatedItems": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": [ 1 ], + "valid": false + } + ] + }, + { + "description": "item is evaluated in an uncle schema to unevaluatedItems", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "prefixItems": [ + { + "type": "string" + } + ], + "unevaluatedItems": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "prefixItems": [ + true, + { + "type": "string" + } + ] + } + } + } + ] + }, + "tests": [ + { + "description": "no extra items", + "data": { + "foo": [ + "test" + ] + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": [ + "test", + "test" + ] + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedItems depends on adjacent contains", + "schema": { + "prefixItems": [true], + "contains": {"type": "string"}, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "second item is evaluated by contains", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "contains fails, second item is not evaluated", + "data": [ 1, 2 ], + "valid": false + }, + { + "description": "contains passes, second item is not evaluated", + "data": [ 1, 2, "foo" ], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems depends on multiple nested contains", + "schema": { + "allOf": [ + { "contains": { "multipleOf": 2 } }, + { "contains": { "multipleOf": 3 } } + ], + "unevaluatedItems": { "multipleOf": 5 } + }, + "tests": [ + { + "description": "5 not evaluated, passes unevaluatedItems", + "data": [ 2, 3, 4, 5, 6 ], + "valid": true + }, + { + "description": "7 not evaluated, fails unevaluatedItems", + "data": [ 2, 3, 4, 7, 8 ], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems and contains interact to control item dependency relationship", + "schema": { + "if": { + "contains": {"const": "a"} + }, + "then": { + "if": { + "contains": {"const": "b"} + }, + "then": { + "if": { + "contains": {"const": "c"} + } + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "empty array is valid", + "data": [], + "valid": true + }, + { + "description": "only a's are valid", + "data": [ "a", "a" ], + "valid": true + }, + { + "description": "a's and b's are valid", + "data": [ "a", "b", "a", "b", "a" ], + "valid": true + }, + { + "description": "a's, b's and c's are valid", + "data": [ "c", "a", "c", "c", "b", "a" ], + "valid": true + }, + { + "description": "only b's are invalid", + "data": [ "b", "b" ], + "valid": false + }, + { + "description": "only c's are invalid", + "data": [ "c", "c" ], + "valid": false + }, + { + "description": "only b's and c's are invalid", + "data": [ "c", "b", "c", "b", "c" ], + "valid": false + }, + { + "description": "only a's and c's are invalid", + "data": [ "c", "a", "c", "a", "c" ], + "valid": false + } + ] + }, + { + "description": "non-array instances are valid", + "schema": {"unevaluatedItems": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/unevaluatedProperties.json python-jsonschema-4.6.0/json/tests/draft2020-12/unevaluatedProperties.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/unevaluatedProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/unevaluatedProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,1347 @@ +[ + { + "description": "unevaluatedProperties true", + "schema": { + "type": "object", + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties schema", + "schema": { + "type": "object", + "unevaluatedProperties": { + "type": "string", + "minLength": 3 + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with valid unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with invalid unevaluated properties", + "data": { + "foo": "fo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties false", + "schema": { + "type": "object", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent patternProperties", + "schema": { + "type": "object", + "patternProperties": { + "^foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "additionalProperties": true, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "properties": { + "bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested patternProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "patternProperties": { + "^bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "additionalProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested unevaluatedProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": { + "type": "string", + "maxLength": 2 + } + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with anyOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "anyOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + }, + { + "properties": { + "quux": { "const": "quux" } + }, + "required": ["quux"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when one matches and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when one matches and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "not-baz" + }, + "valid": false + }, + { + "description": "when two match and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": true + }, + { + "description": "when two match and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz", + "quux": "not-quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with oneOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "oneOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "quux": "quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with not", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "not": { + "not": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, then not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": false + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, else not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with dependentSchemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with boolean schemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [true], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $ref", + "schema": { + "type": "object", + "$ref": "#/$defs/bar", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false, + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties can't see inside cousins", + "schema": { + "allOf": [ + { + "properties": { + "foo": true + } + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": { + "foo": 1 + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, true with properties", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, false with properties", + "schema": { + "type": "object", + "allOf": [ + { + "unevaluatedProperties": true + }, + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "property is evaluated in an uncle schema to unevaluatedProperties", + "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + }, + "unevaluatedProperties": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "properties": { + "faz": { + "type": "string" + } + } + } + } + } + ] + }, + "tests": [ + { + "description": "no extra properties", + "data": { + "foo": { + "bar": "test" + } + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": { + "bar": "test", + "faz": "test" + } + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, allOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + }, + "unevaluatedProperties": false + } + ], + "anyOf": [ + { + "properties": { + "bar": true + } + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": true + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, anyOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + } + } + ], + "anyOf": [ + { + "properties": { + "bar": true + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties + single cyclic ref", + "schema": { + "type": "object", + "properties": { + "x": { "$ref": "#" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is valid", + "data": {}, + "valid": true + }, + { + "description": "Single is valid", + "data": { "x": {} }, + "valid": true + }, + { + "description": "Unevaluated on 1st level is invalid", + "data": { "x": {}, "y": {} }, + "valid": false + }, + { + "description": "Nested is valid", + "data": { "x": { "x": {} } }, + "valid": true + }, + { + "description": "Unevaluated on 2nd level is invalid", + "data": { "x": { "x": {}, "y": {} } }, + "valid": false + }, + { + "description": "Deep nested is valid", + "data": { "x": { "x": { "x": {} } } }, + "valid": true + }, + { + "description": "Unevaluated on 3rd level is invalid", + "data": { "x": { "x": { "x": {}, "y": {} } } }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties + ref inside allOf / oneOf", + "schema": { + "$defs": { + "one": { + "properties": { "a": true } + }, + "two": { + "required": ["x"], + "properties": { "x": true } + } + }, + "allOf": [ + { "$ref": "#/$defs/one" }, + { "properties": { "b": true } }, + { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { + "required": ["y"], + "properties": { "y": true } + } + ] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid (no x or y)", + "data": {}, + "valid": false + }, + { + "description": "a and b are invalid (no x or y)", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "x and y are invalid", + "data": { "x": 1, "y": 1 }, + "valid": false + }, + { + "description": "a and x are valid", + "data": { "a": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and y are valid", + "data": { "a": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x are valid", + "data": { "a": 1, "b": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and b and y are valid", + "data": { "a": 1, "b": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x and y are invalid", + "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, + "valid": false + } + ] + }, + { + "description": "dynamic evalation inside nested refs", + "schema": { + "$defs": { + "one": { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { "required": ["b"], "properties": { "b": true } }, + { "required": ["xx"], "patternProperties": { "x": true } }, + { "required": ["all"], "unevaluatedProperties": true } + ] + }, + "two": { + "oneOf": [ + { "required": ["c"], "properties": { "c": true } }, + { "required": ["d"], "properties": { "d": true } } + ] + } + }, + "oneOf": [ + { "$ref": "#/$defs/one" }, + { "required": ["a"], "properties": { "a": true } } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid", + "data": {}, + "valid": false + }, + { + "description": "a is valid", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "b is valid", + "data": { "b": 1 }, + "valid": true + }, + { + "description": "c is valid", + "data": { "c": 1 }, + "valid": true + }, + { + "description": "d is valid", + "data": { "d": 1 }, + "valid": true + }, + { + "description": "a + b is invalid", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "a + c is invalid", + "data": { "a": 1, "c": 1 }, + "valid": false + }, + { + "description": "a + d is invalid", + "data": { "a": 1, "d": 1 }, + "valid": false + }, + { + "description": "b + c is invalid", + "data": { "b": 1, "c": 1 }, + "valid": false + }, + { + "description": "b + d is invalid", + "data": { "b": 1, "d": 1 }, + "valid": false + }, + { + "description": "c + d is invalid", + "data": { "c": 1, "d": 1 }, + "valid": false + }, + { + "description": "xx is valid", + "data": { "xx": 1 }, + "valid": true + }, + { + "description": "xx + foox is valid", + "data": { "xx": 1, "foox": 1 }, + "valid": true + }, + { + "description": "xx + foo is invalid", + "data": { "xx": 1, "foo": 1 }, + "valid": false + }, + { + "description": "xx + a is invalid", + "data": { "xx": 1, "a": 1 }, + "valid": false + }, + { + "description": "xx + b is invalid", + "data": { "xx": 1, "b": 1 }, + "valid": false + }, + { + "description": "xx + c is invalid", + "data": { "xx": 1, "c": 1 }, + "valid": false + }, + { + "description": "xx + d is invalid", + "data": { "xx": 1, "d": 1 }, + "valid": false + }, + { + "description": "all is valid", + "data": { "all": 1 }, + "valid": true + }, + { + "description": "all + foo is valid", + "data": { "all": 1, "foo": 1 }, + "valid": true + }, + { + "description": "all + a is invalid", + "data": { "all": 1, "a": 1 }, + "valid": false + } + ] + }, + { + "description": "non-object instances are valid", + "schema": {"unevaluatedProperties": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft2020-12/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/uniqueItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,404 @@ +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1, "{}"], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true + } + ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "items": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "items": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/unknownKeyword.json python-jsonschema-4.6.0/json/tests/draft2020-12/unknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/unknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/unknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,56 @@ +[ + { + "description": "$id inside an unknown keyword is not a real identifier", + "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", + "schema": { + "$defs": { + "id_in_unknown0": { + "not": { + "array_of_schemas": [ + { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "null" + } + ] + } + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "string" + }, + "id_in_unknown1": { + "not": { + "object_of_schemas": { + "foo": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "integer" + } + } + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_unknown0" }, + { "$ref": "#/$defs/id_in_unknown1" }, + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "type matches second anyOf, which has a real schema in it", + "data": "a string", + "valid": true + }, + { + "description": "type matches non-schema in first anyOf", + "data": null, + "valid": false + }, + { + "description": "type matches non-schema in third anyOf", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft2020-12/vocabulary.json python-jsonschema-4.6.0/json/tests/draft2020-12/vocabulary.json --- python-jsonschema-3.2.0/json/tests/draft2020-12/vocabulary.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft2020-12/vocabulary.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "schema that uses custom metaschema with with no validation vocabulary", + "schema": { + "$id": "https://schema/using/no/validation", + "$schema": "http://localhost:1234/draft2020-12/metaschema-no-validation.json", + "properties": { + "badProperty": false, + "numberProperty": { + "minimum": 10 + } + } + }, + "tests": [ + { + "description": "applicator vocabulary still works", + "data": { + "badProperty": "this property should not exist" + }, + "valid": false + }, + { + "description": "no validation: valid number", + "data": { + "numberProperty": 20 + }, + "valid": true + }, + { + "description": "no validation: invalid number, but it still validates", + "data": { + "numberProperty": 1 + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/additionalItems.json python-jsonschema-4.6.0/json/tests/draft3/additionalItems.json --- python-jsonschema-3.2.0/json/tests/draft3/additionalItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/additionalItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -19,7 +19,7 @@ ] }, { - "description": "items is schema, no additionalItems", + "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false @@ -33,14 +33,29 @@ ] }, { - "description": "array of items with no additionalItems", + "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { - "description": "no additional items present", + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "equal number of items present", "data": [ 1, 2, 3 ], "valid": true }, @@ -70,13 +85,29 @@ }, { "description": "additionalItems are allowed by default", - "schema": {"items": []}, + "schema": {"items": [{"type": "integer"}]}, "tests": [ { - "description": "only the first items are validated", + "description": "only the first item is validated", "data": [1, "foo", false], "valid": true } ] + }, + { + "description": "additionalItems should not look in applicators", + "schema": { + "extends": [ + { "items": [ { "type": "integer" } ] } + ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in extends are not examined", + "data": [ 1, null ], + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft3/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft3/additionalProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -124,7 +124,7 @@ }, "tests": [ { - "description": "properties defined in extends are not allowed", + "description": "properties defined in extends are not examined", "data": {"foo": 1, "bar": true}, "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft3/default.json python-jsonschema-4.6.0/json/tests/draft3/default.json --- python-jsonschema-3.2.0/json/tests/draft3/default.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,5 +45,35 @@ "valid": true } ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/dependencies.json python-jsonschema-4.6.0/json/tests/draft3/dependencies.json --- python-jsonschema-3.2.0/json/tests/draft3/dependencies.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/dependencies.json 2022-06-01 20:26:26.000000000 +0000 @@ -99,6 +99,11 @@ "valid": true }, { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { "description": "wrong type", "data": {"foo": "quux", "bar": 2}, "valid": false diff -Nru python-jsonschema-3.2.0/json/tests/draft3/enum.json python-jsonschema-4.6.0/json/tests/draft3/enum.json --- python-jsonschema-3.2.0/json/tests/draft3/enum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -37,6 +37,27 @@ ] }, { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false + } + ] + }, + { "description": "enums in properties", "schema": { "type":"object", @@ -52,6 +73,16 @@ "valid": true }, { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true @@ -67,5 +98,21 @@ "valid": false } ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/format.json python-jsonschema-4.6.0/json/tests/draft3/format.json --- python-jsonschema-3.2.0/json/tests/draft3/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,359 +1,359 @@ [ { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "description": "email format", + "schema": { "format": "email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IP addresses", - "schema": {"format": "ip-address"}, + "description": "ip-address format", + "schema": { "format": "ip-address" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "description": "ipv6 format", + "schema": { "format": "ipv6" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of hostnames", - "schema": {"format": "host-name"}, + "description": "host-name format", + "schema": { "format": "host-name" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "description": "date-time format", + "schema": { "format": "date-time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of regular expressions", - "schema": {"format": "regex"}, + "description": "regex format", + "schema": { "format": "regex" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date strings", - "schema": {"format": "date"}, + "description": "date format", + "schema": { "format": "date" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of time strings", - "schema": {"format": "time"}, + "description": "time format", + "schema": { "format": "time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of CSS colors", - "schema": {"format": "color"}, + "description": "color format", + "schema": { "format": "color" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URIs", - "schema": {"format": "uri"}, + "description": "uri format", + "schema": { "format": "uri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } diff -Nru python-jsonschema-3.2.0/json/tests/draft3/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft3/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft3/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,32 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "definitions": { + "int": { "type": "integer" } + }, + "properties": { + "foo": { + "$ref": "#/definitions/int" + } + }, + "extends": { + "additionalProperties": { + "$ref": "#/definitions/int" + } + } + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/maximum.json python-jsonschema-4.6.0/json/tests/draft3/maximum.json --- python-jsonschema-3.2.0/json/tests/draft3/maximum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -9,6 +9,63 @@ "valid": true }, { + "description": "boundary point is valid", + "data": 3.0, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] + }, + { + "description": "maximum validation (explicit false exclusivity)", + "schema": {"maximum": 3.0, "exclusiveMaximum": false}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "boundary point is valid", + "data": 3.0, + "valid": true + }, + { "description": "above the maximum is invalid", "data": 3.5, "valid": false diff -Nru python-jsonschema-3.2.0/json/tests/draft3/minimum.json python-jsonschema-4.6.0/json/tests/draft3/minimum.json --- python-jsonschema-3.2.0/json/tests/draft3/minimum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -9,6 +9,11 @@ "valid": true }, { + "description": "boundary point is valid", + "data": 1.1, + "valid": true + }, + { "description": "below the minimum is invalid", "data": 0.6, "valid": false @@ -59,7 +64,17 @@ "valid": true }, { - "description": "below the minimum is invalid", + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", "data": -3, "valid": false }, diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/color.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/color.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/color.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/color.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "validation of CSS colors", + "schema": { "format": "color" }, + "tests": [ + { + "description": "a valid CSS color name", + "data": "fuchsia", + "valid": true + }, + { + "description": "a valid six-digit CSS color code", + "data": "#CC8899", + "valid": true + }, + { + "description": "a valid three-digit CSS color code", + "data": "#C89", + "valid": true + }, + { + "description": "an invalid CSS color code", + "data": "#00332520", + "valid": false + }, + { + "description": "an invalid CSS color name", + "data": "puce", + "valid": false + }, + { + "description": "a CSS color name containing invalid characters", + "data": "light_grayish_red-violet", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/date.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/date.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/date.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/date.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,168 @@ +[ + { + "description": "validation of date strings", + "schema": { "format": "date" }, + "tests": [ + { + "description": "a valid date string", + "data": "1963-06-19", + "valid": true + }, + { + "description": "a valid date string with 31 days in January", + "data": "2020-01-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in January", + "data": "2020-01-32", + "valid": false + }, + { + "description": "a valid date string with 28 days in February (normal)", + "data": "2021-02-28", + "valid": true + }, + { + "description": "a invalid date string with 29 days in February (normal)", + "data": "2021-02-29", + "valid": false + }, + { + "description": "a valid date string with 29 days in February (leap)", + "data": "2020-02-29", + "valid": true + }, + { + "description": "a invalid date string with 30 days in February (leap)", + "data": "2020-02-30", + "valid": false + }, + { + "description": "a valid date string with 31 days in March", + "data": "2020-03-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in March", + "data": "2020-03-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in April", + "data": "2020-04-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in April", + "data": "2020-04-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in May", + "data": "2020-05-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in May", + "data": "2020-05-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in June", + "data": "2020-06-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in June", + "data": "2020-06-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in July", + "data": "2020-07-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in July", + "data": "2020-07-32", + "valid": false + }, + { + "description": "a valid date string with 31 days in August", + "data": "2020-08-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in August", + "data": "2020-08-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in September", + "data": "2020-09-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in September", + "data": "2020-09-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in October", + "data": "2020-10-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in October", + "data": "2020-10-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in November", + "data": "2020-11-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in November", + "data": "2020-11-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in December", + "data": "2020-12-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in December", + "data": "2020-12-32", + "valid": false + }, + { + "description": "a invalid date string with invalid month", + "data": "2020-13-01", + "valid": false + }, + { + "description": "an invalid date string", + "data": "06/19/1963", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350", + "valid": false + }, + { + "description": "invalidates non-padded month dates", + "data": "1998-1-20", + "valid": false + }, + { + "description": "invalidates non-padded day dates", + "data": "1998-01-1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/date-time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "validation of date-time strings", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "case-insensitive T and Z", + "data": "1963-06-19t08:30:06.283185z", + "valid": true + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,53 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": { "format": "email" }, + "tests": [ + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/host-name.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/host-name.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/host-name.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/host-name.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,63 @@ +[ + { + "description": "validation of host names", + "schema": { "format": "host-name" }, + "tests": [ + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/ip-address.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/ip-address.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/ip-address.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/ip-address.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,23 @@ +[ + { + "description": "validation of IP addresses", + "schema": { "format": "ip-address" }, + "tests": [ + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/ipv6.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,68 @@ +[ + { + "description": "validation of IPv6 addresses", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/regex.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/regex.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,18 @@ +[ + { + "description": "validation of regular expressions", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "a valid regular expression", + "data": "([abc])+\\s+$", + "valid": true + }, + { + "description": "a regular expression with unclosed parens is invalid", + "data": "^(abc]", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/time.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/time.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,18 @@ +[ + { + "description": "validation of time strings", + "schema": { "format": "time" }, + "tests": [ + { + "description": "a valid time string", + "data": "08:30:06", + "valid": true + }, + { + "description": "an invalid time string", + "data": "8:30 AM", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft3/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format/uri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,28 @@ +[ + { + "description": "validation of URIs", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "an invalid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": false + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/format.json python-jsonschema-4.6.0/json/tests/draft3/optional/format.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/format.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +0,0 @@ -[ - { - "description": "validation of regular expressions", - "schema": {"format": "regex"}, - "tests": [ - { - "description": "a valid regular expression", - "data": "([abc])+\\s+$", - "valid": true - }, - { - "description": "a regular expression with unclosed parens is invalid", - "data": "^(abc]", - "valid": false - } - ] - }, - { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, - "tests": [ - { - "description": "a valid date-time string", - "data": "1963-06-19T08:30:06.283185Z", - "valid": true - }, - { - "description": "an invalid date-time string", - "data": "06/19/1963 08:30:06 PST", - "valid": false - }, - { - "description": "case-insensitive T and Z", - "data": "1963-06-19t08:30:06.283185z", - "valid": true - }, - { - "description": "only RFC3339 not all of ISO 8601 are valid", - "data": "2013-350T01:01:01", - "valid": false - } - ] - }, - { - "description": "validation of date strings", - "schema": {"format": "date"}, - "tests": [ - { - "description": "a valid date string", - "data": "1963-06-19", - "valid": true - }, - { - "description": "an invalid date string", - "data": "06/19/1963", - "valid": false - } - ] - }, - { - "description": "validation of time strings", - "schema": {"format": "time"}, - "tests": [ - { - "description": "a valid time string", - "data": "08:30:06", - "valid": true - }, - { - "description": "an invalid time string", - "data": "8:30 AM", - "valid": false - } - ] - }, - { - "description": "validation of URIs", - "schema": {"format": "uri"}, - "tests": [ - { - "description": "a valid URI", - "data": "http://foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "an invalid protocol-relative URI Reference", - "data": "//foo.bar/?baz=qux#quux", - "valid": false - }, - { - "description": "an invalid URI", - "data": "\\\\WINDOWS\\fileshare", - "valid": false - }, - { - "description": "an invalid URI though valid URI reference", - "data": "abc", - "valid": false - } - ] - }, - { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, - "tests": [ - { - "description": "a valid e-mail address", - "data": "joe.bloggs@example.com", - "valid": true - }, - { - "description": "an invalid e-mail address", - "data": "2962", - "valid": false - } - ] - }, - { - "description": "validation of IP addresses", - "schema": {"format": "ip-address"}, - "tests": [ - { - "description": "a valid IP address", - "data": "192.168.0.1", - "valid": true - }, - { - "description": "an IP address with too many components", - "data": "127.0.0.0.1", - "valid": false - }, - { - "description": "an IP address with out-of-range values", - "data": "256.256.256.256", - "valid": false - } - ] - }, - { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, - "tests": [ - { - "description": "a valid IPv6 address", - "data": "::1", - "valid": true - }, - { - "description": "an IPv6 address with out-of-range values", - "data": "12345::", - "valid": false - }, - { - "description": "an IPv6 address with too many components", - "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", - "valid": false - }, - { - "description": "an IPv6 address containing illegal characters", - "data": "::laptop", - "valid": false - } - ] - }, - { - "description": "validation of host names", - "schema": {"format": "host-name"}, - "tests": [ - { - "description": "a valid host name", - "data": "www.example.com", - "valid": true - }, - { - "description": "a host name starting with an illegal character", - "data": "-a-host-name-that-starts-with--", - "valid": false - }, - { - "description": "a host name containing illegal characters", - "data": "not_a_valid_host_name", - "valid": false - }, - { - "description": "a host name with a component too long", - "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", - "valid": false - } - ] - }, - { - "description": "validation of CSS colors", - "schema": {"format": "color"}, - "tests": [ - { - "description": "a valid CSS color name", - "data": "fuchsia", - "valid": true - }, - { - "description": "a valid six-digit CSS color code", - "data": "#CC8899", - "valid": true - }, - { - "description": "a valid three-digit CSS color code", - "data": "#C89", - "valid": true - }, - { - "description": "an invalid CSS color code", - "data": "#00332520", - "valid": false - }, - { - "description": "an invalid CSS color name", - "data": "puce", - "valid": false - }, - { - "description": "a CSS color name containing invalid characters", - "data": "light_grayish_red-violet", - "valid": false - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft3/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft3/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/pattern.json python-jsonschema-4.6.0/json/tests/draft3/pattern.json --- python-jsonschema-3.2.0/json/tests/draft3/pattern.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,9 +14,34 @@ "valid": false }, { - "description": "ignores non-strings", + "description": "ignores booleans", "data": true, "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true } ] }, diff -Nru python-jsonschema-3.2.0/json/tests/draft3/ref.json python-jsonschema-4.6.0/json/tests/draft3/ref.json --- python-jsonschema-3.2.0/json/tests/draft3/ref.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ @@ -91,8 +93,8 @@ "valid": false }, { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, "valid": false }, { @@ -106,8 +108,8 @@ "valid": true }, { - "description": "tilda valid", - "data": {"tilda": 123}, + "description": "tilde valid", + "data": {"tilde": 123}, "valid": true }, { @@ -174,6 +176,67 @@ ] }, { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/definitions/is-string"} + }, + "definitions": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { + "description": "$ref prevents a sibling id from changing the base uri", + "schema": { + "id": "http://localhost:1234/sibling_id/base/", + "definitions": { + "foo": { + "id": "http://localhost:1234/sibling_id/foo.json", + "type": "string" + }, + "base_foo": { + "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", + "id": "foo.json", + "type": "number" + } + }, + "allOf": [ + { + "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", + "id": "http://localhost:1234/sibling_id/", + "$ref": "foo.json" + } + ] + }, + "tests": [ + { + "description": "$ref resolves to /definitions/base_foo, data does not validate", + "data": "a", + "valid": false + }, + { + "description": "$ref resolves to /definitions/base_foo, data validates", + "data": 1, + "valid": true + } + ] + }, + { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-03/schema#"}, "tests": [ @@ -188,5 +251,28 @@ "valid": false } ] + }, + { + "description": "naive replacement of $ref with its destination is not correct", + "schema": { + "definitions": { + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/definitions/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/definitions/a_string" }, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft3/refRemote.json python-jsonschema-4.6.0/json/tests/draft3/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft3/refRemote.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -54,7 +54,7 @@ "schema": { "id": "http://localhost:1234/", "items": { - "id": "folder/", + "id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, diff -Nru python-jsonschema-3.2.0/json/tests/draft3/type.json python-jsonschema-4.6.0/json/tests/draft3/type.json --- python-jsonschema-3.2.0/json/tests/draft3/type.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -55,6 +55,11 @@ "valid": true }, { + "description": "a float with zero fractional part is a number", + "data": 1.0, + "valid": true + }, + { "description": "a float is a number", "data": 1.1, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft3/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft3/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft3/uniqueItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft3/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,11 +14,26 @@ "valid": false }, { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false }, { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true @@ -55,6 +70,11 @@ "valid": false }, { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { "description": "1 and true are unique", "data": [1, true], "valid": true @@ -65,6 +85,26 @@ "valid": true }, { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { "description": "unique heterogeneous types are valid", "data": [{}, [1], true, null, 1], "valid": true @@ -73,13 +113,23 @@ "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], + "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ @@ -128,8 +178,8 @@ { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], - "uniqueItems": true, + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, "additionalItems": false }, "tests": [ @@ -155,6 +205,167 @@ }, { "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft4/additionalItems.json python-jsonschema-4.6.0/json/tests/draft4/additionalItems.json --- python-jsonschema-3.2.0/json/tests/draft4/additionalItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/additionalItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -19,7 +19,7 @@ ] }, { - "description": "items is schema, no additionalItems", + "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false @@ -33,14 +33,24 @@ ] }, { - "description": "array of items with no additionalItems", + "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { - "description": "fewer number of items present", + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, @@ -83,5 +93,57 @@ "valid": true } ] + }, + { + "description": "additionalItems should not look in applicators, valid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" } ] } + ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, null ], + "valid": true + } + ] + }, + { + "description": "additionalItems should not look in applicators, invalid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" }, { "type": "string" } ] } + ], + "items": [ {"type": "integer" } ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, "hello" ], + "valid": false + } + ] + }, + { + "description": "items validation adjusts the starting index for additionalItems", + "schema": { + "items": [ { "type": "string" } ], + "additionalItems": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft4/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft4/additionalProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -124,7 +124,7 @@ }, "tests": [ { - "description": "properties defined in allOf are not allowed", + "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft4/allOf.json python-jsonschema-4.6.0/json/tests/draft4/allOf.json --- python-jsonschema-3.2.0/json/tests/draft4/allOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -181,5 +181,81 @@ "valid": false } ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/anyOf.json python-jsonschema-4.6.0/json/tests/draft4/anyOf.json --- python-jsonschema-3.2.0/json/tests/draft4/anyOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/anyOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -152,5 +152,31 @@ "valid": false } ] + }, + { + "description": "nested anyOf, to check validation semantics", + "schema": { + "anyOf": [ + { + "anyOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/default.json python-jsonschema-4.6.0/json/tests/draft4/default.json --- python-jsonschema-3.2.0/json/tests/draft4/default.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,5 +45,35 @@ "valid": true } ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/definitions.json python-jsonschema-4.6.0/json/tests/draft4/definitions.json --- python-jsonschema-3.2.0/json/tests/draft4/definitions.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/definitions.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,6 +1,6 @@ [ { - "description": "valid definition", + "description": "validate definition against metaschema", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, "tests": [ { @@ -11,13 +11,7 @@ } }, "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, - "tests": [ + }, { "description": "invalid definition schema", "data": { diff -Nru python-jsonschema-3.2.0/json/tests/draft4/enum.json python-jsonschema-4.6.0/json/tests/draft4/enum.json --- python-jsonschema-3.2.0/json/tests/draft4/enum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -33,6 +33,37 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false } ] }, @@ -53,6 +84,16 @@ "valid": true }, { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true @@ -175,5 +216,21 @@ "valid": true } ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/format.json python-jsonschema-4.6.0/json/tests/draft4/format.json --- python-jsonschema-3.2.0/json/tests/draft4/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,215 +1,215 @@ [ { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "description": "email format", + "schema": { "format": "email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "description": "ipv4 format", + "schema": { "format": "ipv4" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "description": "ipv6 format", + "schema": { "format": "ipv6" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of hostnames", - "schema": {"format": "hostname"}, + "description": "hostname format", + "schema": { "format": "hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "description": "date-time format", + "schema": { "format": "date-time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URIs", - "schema": {"format": "uri"}, + "description": "uri format", + "schema": { "format": "uri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } diff -Nru python-jsonschema-3.2.0/json/tests/draft4/id.json python-jsonschema-4.6.0/json/tests/draft4/id.json --- python-jsonschema-3.2.0/json/tests/draft4/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,53 @@ +[ + { + "description": "id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an id buried in the enum", + "schema": { + "definitions": { + "id_in_enum": { + "enum": [ + { + "id": "https://localhost:1234/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "id": "https://localhost:1234/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "id": "https://localhost:1234/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/definitions/id_in_enum" }, + { "$ref": "https://localhost:1234/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "id": "https://localhost:1234/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to id", + "data": "a string to match #/definitions/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to id", + "data": 1, + "valid": false + } + ] + } + +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft4/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft4/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "definitions": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/definitions/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/definitions/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/maximum.json python-jsonschema-4.6.0/json/tests/draft4/maximum.json --- python-jsonschema-3.2.0/json/tests/draft4/maximum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -26,6 +26,32 @@ ] }, { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] + }, + { "description": "maximum validation (explicit false exclusivity)", "schema": {"maximum": 3.0, "exclusiveMaximum": false}, "tests": [ diff -Nru python-jsonschema-3.2.0/json/tests/draft4/maxProperties.json python-jsonschema-4.6.0/json/tests/draft4/maxProperties.json --- python-jsonschema-3.2.0/json/tests/draft4/maxProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -34,5 +34,21 @@ "valid": true } ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/minimum.json python-jsonschema-4.6.0/json/tests/draft4/minimum.json --- python-jsonschema-3.2.0/json/tests/draft4/minimum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -90,7 +90,17 @@ "valid": true }, { - "description": "below the minimum is invalid", + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", "data": -3, "valid": false }, diff -Nru python-jsonschema-3.2.0/json/tests/draft4/multipleOf.json python-jsonschema-4.6.0/json/tests/draft4/multipleOf.json --- python-jsonschema-3.2.0/json/tests/draft4/multipleOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/oneOf.json python-jsonschema-4.6.0/json/tests/draft4/oneOf.json --- python-jsonschema-3.2.0/json/tests/draft4/oneOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -158,5 +158,73 @@ "valid": false } ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": {}, + "baz": {} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/bignum.json python-jsonschema-4.6.0/json/tests/draft4/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/bignum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,30 +1,13 @@ [ { "description": "integer", - "schema": {"type": "integer"}, + "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ + }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, @@ -34,9 +17,14 @@ }, { "description": "number", - "schema": {"type": "number"}, + "schema": { "type": "number" }, "tests": [ { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true @@ -45,7 +33,7 @@ }, { "description": "string", - "schema": {"type": "string"}, + "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", @@ -56,7 +44,7 @@ }, { "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, + "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", @@ -81,7 +69,7 @@ }, { "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, + "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/draft4/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/ecmascript-regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", @@ -19,7 +8,7 @@ "tests": [ { "description": "matches in Python, but should not in jsonschema", - "data": "abc\n", + "data": "abc\\n", "valid": false }, { @@ -30,20 +19,20 @@ ] }, { - "description": "ECMA 262 regex converts \\a to ascii BEL", + "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", - "pattern": "^\\a$" + "pattern": "^\\t$" }, "tests": [ { "description": "does not match", - "data": "\\a", + "data": "\\t", "valid": false }, { "description": "matches", - "data": "\u0007", + "data": "\u0009", "valid": true } ] @@ -154,7 +143,7 @@ ] }, { - "description": "ECMA 262 \\w matches everything but ascii letters", + "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" @@ -173,7 +162,7 @@ ] }, { - "description": "ECMA 262 \\s matches ascii whitespace only", + "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" @@ -185,14 +174,59 @@ "valid": true }, { - "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", "valid": false } ] }, { - "description": "ECMA 262 \\S matches everything but ascii whitespace", + "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" @@ -204,8 +238,313 @@ "valid": false }, { - "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": {} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": {} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": {} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": {} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": {} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/draft4/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "number", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/date-time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,133 @@ +[ + { + "description": "validation of date-time strings", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "a valid date-time string without second fraction", + "data": "1963-06-19T08:30:06Z", + "valid": true + }, + { + "description": "a valid date-time string with plus offset", + "data": "1937-01-01T12:00:27.87+00:20", + "valid": true + }, + { + "description": "a valid date-time string with minus offset", + "data": "1990-12-31T15:59:50.123-08:00", + "valid": true + }, + { + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", + "valid": false + }, + { + "description": "an invalid offset in date-time string", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", + "valid": false + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "case-insensitive T and Z", + "data": "1963-06-19t08:30:06.283185z", + "valid": true + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,83 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": { "format": "email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/hostname.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,98 @@ +[ + { + "description": "validation of host names", + "schema": { "format": "hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a valid punycoded IDN hostname", + "data": "xn--4gbwdl.xn--wgbh1c", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/ipv4.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,84 @@ +[ + { + "description": "validation of IP addresses", + "schema": { "format": "ipv4" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/ipv6.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,208 @@ +[ + { + "description": "validation of IPv6 addresses", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/unknown.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/unknown.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/unknown.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/unknown.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,43 @@ +[ + { + "description": "unknown format", + "schema": { "format": "unknown" }, + "tests": [ + { + "description": "unknown formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "unknown formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "unknown formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "unknown formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "unknown formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "unknown formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "unknown formats ignore strings", + "data": "string", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft4/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format/uri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,108 @@ +[ + { + "description": "validation of URIs", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "a valid URL with anchor tag", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid URL with anchor tag and parentheses", + "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", + "valid": true + }, + { + "description": "a valid URL with URL-encoded stuff", + "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", + "valid": true + }, + { + "description": "a valid puny-coded URL ", + "data": "http://xn--nw2a.xn--j6w193g/", + "valid": true + }, + { + "description": "a valid URL with many special characters", + "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", + "valid": true + }, + { + "description": "a valid URL based on IPv4", + "data": "http://223.255.255.254", + "valid": true + }, + { + "description": "a valid URL with ftp scheme", + "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", + "valid": true + }, + { + "description": "a valid URL for a simple text file", + "data": "http://www.ietf.org/rfc/rfc2396.txt", + "valid": true + }, + { + "description": "a valid URL ", + "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", + "valid": true + }, + { + "description": "a valid mailto URI", + "data": "mailto:John.Doe@example.com", + "valid": true + }, + { + "description": "a valid newsgroup URI", + "data": "news:comp.infosystems.www.servers.unix", + "valid": true + }, + { + "description": "a valid tel URI", + "data": "tel:+1-816-555-1212", + "valid": true + }, + { + "description": "a valid URN", + "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", + "valid": true + }, + { + "description": "an invalid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": false + }, + { + "description": "an invalid relative URI Reference", + "data": "/abc", + "valid": false + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + }, + { + "description": "an invalid URI with spaces", + "data": "http:// shouldfail.com", + "valid": false + }, + { + "description": "an invalid URI with spaces and missing scheme", + "data": ":// should fail", + "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/format.json python-jsonschema-4.6.0/json/tests/draft4/optional/format.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/format.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,253 +0,0 @@ -[ - { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, - "tests": [ - { - "description": "a valid date-time string", - "data": "1963-06-19T08:30:06.283185Z", - "valid": true - }, - { - "description": "a valid date-time string without second fraction", - "data": "1963-06-19T08:30:06Z", - "valid": true - }, - { - "description": "a valid date-time string with plus offset", - "data": "1937-01-01T12:00:27.87+00:20", - "valid": true - }, - { - "description": "a valid date-time string with minus offset", - "data": "1990-12-31T15:59:50.123-08:00", - "valid": true - }, - { - "description": "a invalid day in date-time string", - "data": "1990-02-31T15:59:60.123-08:00", - "valid": false - }, - { - "description": "an invalid offset in date-time string", - "data": "1990-12-31T15:59:60-24:00", - "valid": false - }, - { - "description": "an invalid date-time string", - "data": "06/19/1963 08:30:06 PST", - "valid": false - }, - { - "description": "case-insensitive T and Z", - "data": "1963-06-19t08:30:06.283185z", - "valid": true - }, - { - "description": "only RFC3339 not all of ISO 8601 are valid", - "data": "2013-350T01:01:01", - "valid": false - } - ] - }, - { - "description": "validation of URIs", - "schema": {"format": "uri"}, - "tests": [ - { - "description": "a valid URL with anchor tag", - "data": "http://foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "a valid URL with anchor tag and parantheses", - "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", - "valid": true - }, - { - "description": "a valid URL with URL-encoded stuff", - "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", - "valid": true - }, - { - "description": "a valid puny-coded URL ", - "data": "http://xn--nw2a.xn--j6w193g/", - "valid": true - }, - { - "description": "a valid URL with many special characters", - "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", - "valid": true - }, - { - "description": "a valid URL based on IPv4", - "data": "http://223.255.255.254", - "valid": true - }, - { - "description": "a valid URL with ftp scheme", - "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", - "valid": true - }, - { - "description": "a valid URL for a simple text file", - "data": "http://www.ietf.org/rfc/rfc2396.txt", - "valid": true - }, - { - "description": "a valid URL ", - "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", - "valid": true - }, - { - "description": "a valid mailto URI", - "data": "mailto:John.Doe@example.com", - "valid": true - }, - { - "description": "a valid newsgroup URI", - "data": "news:comp.infosystems.www.servers.unix", - "valid": true - }, - { - "description": "a valid tel URI", - "data": "tel:+1-816-555-1212", - "valid": true - }, - { - "description": "a valid URN", - "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", - "valid": true - }, - { - "description": "an invalid protocol-relative URI Reference", - "data": "//foo.bar/?baz=qux#quux", - "valid": false - }, - { - "description": "an invalid relative URI Reference", - "data": "/abc", - "valid": false - }, - { - "description": "an invalid URI", - "data": "\\\\WINDOWS\\fileshare", - "valid": false - }, - { - "description": "an invalid URI though valid URI reference", - "data": "abc", - "valid": false - }, - { - "description": "an invalid URI with spaces", - "data": "http:// shouldfail.com", - "valid": false - }, - { - "description": "an invalid URI with spaces and missing scheme", - "data": ":// should fail", - "valid": false - } - ] - }, - { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, - "tests": [ - { - "description": "a valid e-mail address", - "data": "joe.bloggs@example.com", - "valid": true - }, - { - "description": "an invalid e-mail address", - "data": "2962", - "valid": false - } - ] - }, - { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, - "tests": [ - { - "description": "a valid IP address", - "data": "192.168.0.1", - "valid": true - }, - { - "description": "an IP address with too many components", - "data": "127.0.0.0.1", - "valid": false - }, - { - "description": "an IP address with out-of-range values", - "data": "256.256.256.256", - "valid": false - }, - { - "description": "an IP address without 4 components", - "data": "127.0", - "valid": false - }, - { - "description": "an IP address as an integer", - "data": "0x7f000001", - "valid": false - } - ] - }, - { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, - "tests": [ - { - "description": "a valid IPv6 address", - "data": "::1", - "valid": true - }, - { - "description": "an IPv6 address with out-of-range values", - "data": "12345::", - "valid": false - }, - { - "description": "an IPv6 address with too many components", - "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", - "valid": false - }, - { - "description": "an IPv6 address containing illegal characters", - "data": "::laptop", - "valid": false - } - ] - }, - { - "description": "validation of host names", - "schema": {"format": "hostname"}, - "tests": [ - { - "description": "a valid host name", - "data": "www.example.com", - "valid": true - }, - { - "description": "a host name starting with an illegal character", - "data": "-a-host-name-that-starts-with--", - "valid": false - }, - { - "description": "a host name containing illegal characters", - "data": "not_a_valid_host_name", - "valid": false - }, - { - "description": "a host name with a component too long", - "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", - "valid": false - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft4/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft4/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/pattern.json python-jsonschema-4.6.0/json/tests/draft4/pattern.json --- python-jsonschema-3.2.0/json/tests/draft4/pattern.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,9 +14,34 @@ "valid": false }, { - "description": "ignores non-strings", + "description": "ignores booleans", "data": true, "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true } ] }, diff -Nru python-jsonschema-3.2.0/json/tests/draft4/ref.json python-jsonschema-4.6.0/json/tests/draft4/ref.json --- python-jsonschema-3.2.0/json/tests/draft4/ref.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ @@ -91,8 +93,8 @@ "valid": false }, { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, "valid": false }, { @@ -106,8 +108,8 @@ "valid": true }, { - "description": "tilda valid", - "data": {"tilda": 123}, + "description": "tilde valid", + "data": {"tilde": 123}, "valid": true }, { @@ -125,7 +127,7 @@ "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, - "$ref": "#/definitions/c" + "allOf": [{ "$ref": "#/definitions/c" }] }, "tests": [ { @@ -174,6 +176,42 @@ ] }, { + "description": "$ref prevents a sibling id from changing the base uri", + "schema": { + "id": "http://localhost:1234/sibling_id/base/", + "definitions": { + "foo": { + "id": "http://localhost:1234/sibling_id/foo.json", + "type": "string" + }, + "base_foo": { + "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", + "id": "foo.json", + "type": "number" + } + }, + "allOf": [ + { + "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", + "id": "http://localhost:1234/sibling_id/", + "$ref": "foo.json" + } + ] + }, + "tests": [ + { + "description": "$ref resolves to /definitions/base_foo, data does not validate", + "data": "a", + "valid": false + }, + { + "description": "$ref resolves to /definitions/base_foo, data validates", + "data": 1, + "valid": true + } + ] + }, + { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, "tests": [ @@ -210,6 +248,31 @@ ] }, { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/definitions/is-string"} + }, + "definitions": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { "description": "Recursive references between schemas", "schema": { "id": "http://localhost:1234/tree", @@ -351,15 +414,21 @@ ] }, { - "description": "Location-independent identifier with absolute URI", + "description": "Location-independent identifier with base URI change in subschema", "schema": { + "id": "http://localhost:1234/root", "allOf": [{ - "$ref": "http://localhost:1234/bar#foo" + "$ref": "http://localhost:1234/nested.json#foo" }], "definitions": { "A": { - "id": "http://localhost:1234/bar#foo", - "type": "integer" + "id": "nested.json", + "definitions": { + "B": { + "id": "#foo", + "type": "integer" + } + } } } }, @@ -377,33 +446,60 @@ ] }, { - "description": "Location-independent identifier with base URI change in subschema", + "description": "naive replacement of $ref with its destination is not correct", "schema": { - "id": "http://localhost:1234/root", - "allOf": [{ - "$ref": "http://localhost:1234/nested.json#foo" - }], "definitions": { - "A": { - "id": "nested.json", - "definitions": { - "B": { - "id": "#foo", - "type": "integer" + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/definitions/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/definitions/a_string" }, + "valid": true + } + ] + }, + { + "description": "id must be resolved against nearest parent, not just immediate parent", + "schema": { + "id": "http://example.com/a.json", + "definitions": { + "x": { + "id": "http://example.com/b/c.json", + "not": { + "definitions": { + "y": { + "id": "d.json", + "type": "number" + } } } } - } + }, + "allOf": [ + { + "$ref": "http://example.com/b/d.json" + } + ] }, "tests": [ { + "description": "number should pass", "data": 1, - "description": "match", "valid": true }, { + "description": "non-number should fail", "data": "a", - "description": "mismatch", "valid": false } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft4/refRemote.json python-jsonschema-4.6.0/json/tests/draft4/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft4/refRemote.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -54,7 +54,7 @@ "schema": { "id": "http://localhost:1234/", "items": { - "id": "folder/", + "id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, @@ -81,7 +81,7 @@ }, "definitions": { "baz": { - "id": "folder/", + "id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } @@ -110,7 +110,7 @@ }, "definitions": { "baz": { - "id": "folder/", + "id": "baseUriChangeFolderInSubschema/", "definitions": { "bar": { "type": "array", diff -Nru python-jsonschema-3.2.0/json/tests/draft4/type.json python-jsonschema-4.6.0/json/tests/draft4/type.json --- python-jsonschema-3.2.0/json/tests/draft4/type.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -55,6 +55,11 @@ "valid": true }, { + "description": "a float with zero fractional part is a number", + "data": 1.0, + "valid": true + }, + { "description": "a float is a number", "data": 1.1, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft4/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft4/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft4/uniqueItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft4/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,6 +14,11 @@ "valid": false }, { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false @@ -29,6 +34,16 @@ "valid": true }, { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true @@ -65,6 +80,11 @@ "valid": false }, { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { "description": "1 and true are unique", "data": [1, true], "valid": true @@ -75,21 +95,61 @@ "valid": true }, { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], + "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], + "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ @@ -138,8 +198,8 @@ { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], - "uniqueItems": true, + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, "additionalItems": false }, "tests": [ @@ -165,6 +225,177 @@ }, { "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft6/additionalItems.json python-jsonschema-4.6.0/json/tests/draft6/additionalItems.json --- python-jsonschema-3.2.0/json/tests/draft6/additionalItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/additionalItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -19,7 +19,7 @@ ] }, { - "description": "items is schema, no additionalItems", + "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false @@ -33,14 +33,24 @@ ] }, { - "description": "array of items with no additionalItems", + "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { - "description": "fewer number of items present", + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, @@ -83,5 +93,57 @@ "valid": true } ] + }, + { + "description": "additionalItems should not look in applicators, valid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" } ] } + ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, null ], + "valid": true + } + ] + }, + { + "description": "additionalItems should not look in applicators, invalid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" }, { "type": "string" } ] } + ], + "items": [ {"type": "integer" } ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, "hello" ], + "valid": false + } + ] + }, + { + "description": "items validation adjusts the starting index for additionalItems", + "schema": { + "items": [ { "type": "string" } ], + "additionalItems": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft6/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft6/additionalProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -124,7 +124,7 @@ }, "tests": [ { - "description": "properties defined in allOf are not allowed", + "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft6/allOf.json python-jsonschema-4.6.0/json/tests/draft6/allOf.json --- python-jsonschema-3.2.0/json/tests/draft6/allOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -214,5 +214,81 @@ "valid": false } ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/anyOf.json python-jsonschema-4.6.0/json/tests/draft6/anyOf.json --- python-jsonschema-3.2.0/json/tests/draft6/anyOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/anyOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -185,5 +185,31 @@ "valid": false } ] + }, + { + "description": "nested anyOf, to check validation semantics", + "schema": { + "anyOf": [ + { + "anyOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/const.json python-jsonschema-4.6.0/json/tests/draft6/const.json --- python-jsonschema-3.2.0/json/tests/draft6/const.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/const.json 2022-06-01 20:26:26.000000000 +0000 @@ -126,7 +126,91 @@ ] }, { - "description": "const with 0 does not match false", + "description": "const with [false] does not match [0]", + "schema": {"const": [false]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, + { + "description": "const with [true] does not match [1]", + "schema": {"const": [true]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, + { + "description": "const with {\"a\": false} does not match {\"a\": 0}", + "schema": {"const": {"a": false}}, + "tests": [ + { + "description": "{\"a\": false} is valid", + "data": {"a": false}, + "valid": true + }, + { + "description": "{\"a\": 0} is invalid", + "data": {"a": 0}, + "valid": false + }, + { + "description": "{\"a\": 0.0} is invalid", + "data": {"a": 0.0}, + "valid": false + } + ] + }, + { + "description": "const with {\"a\": true} does not match {\"a\": 1}", + "schema": {"const": {"a": true}}, + "tests": [ + { + "description": "{\"a\": true} is valid", + "data": {"a": true}, + "valid": true + }, + { + "description": "{\"a\": 1} is invalid", + "data": {"a": 1}, + "valid": false + }, + { + "description": "{\"a\": 1.0} is invalid", + "data": {"a": 1.0}, + "valid": false + } + ] + }, + { + "description": "const with 0 does not match other zero-like types", "schema": {"const": 0}, "tests": [ { @@ -143,6 +227,21 @@ "description": "float zero is valid", "data": 0.0, "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "empty string is invalid", + "data": "", + "valid": false } ] }, @@ -166,5 +265,78 @@ "valid": true } ] + }, + { + "description": "const with -2.0 matches integer and float types", + "schema": {"const": -2.0}, + "tests": [ + { + "description": "integer -2 is valid", + "data": -2, + "valid": true + }, + { + "description": "integer 2 is invalid", + "data": 2, + "valid": false + }, + { + "description": "float -2.0 is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float 2.0 is invalid", + "data": 2.0, + "valid": false + }, + { + "description": "float -2.00001 is invalid", + "data": -2.00001, + "valid": false + } + ] + }, + { + "description": "float and integers are equal up to 64-bit representation limits", + "schema": {"const": 9007199254740992}, + "tests": [ + { + "description": "integer is valid", + "data": 9007199254740992, + "valid": true + }, + { + "description": "integer minus one is invalid", + "data": 9007199254740991, + "valid": false + }, + { + "description": "float is valid", + "data": 9007199254740992.0, + "valid": true + }, + { + "description": "float minus one is invalid", + "data": 9007199254740991.0, + "valid": false + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "const": "hello\u0000there" }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/contains.json python-jsonschema-4.6.0/json/tests/draft6/contains.json --- python-jsonschema-3.2.0/json/tests/draft6/contains.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/contains.json 2022-06-01 20:26:26.000000000 +0000 @@ -96,5 +96,34 @@ "valid": true } ] + }, + { + "description": "items + contains", + "schema": { + "items": { "multipleOf": 2 }, + "contains": { "multipleOf": 3 } + }, + "tests": [ + { + "description": "matches items, does not match contains", + "data": [ 2, 4, 8 ], + "valid": false + }, + { + "description": "does not match items, matches contains", + "data": [ 3, 6, 9 ], + "valid": false + }, + { + "description": "matches both items and contains", + "data": [ 6, 12 ], + "valid": true + }, + { + "description": "matches neither items nor contains", + "data": [ 1, 5 ], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/default.json python-jsonschema-4.6.0/json/tests/draft6/default.json --- python-jsonschema-3.2.0/json/tests/draft6/default.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,5 +45,35 @@ "valid": true } ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/definitions.json python-jsonschema-4.6.0/json/tests/draft6/definitions.json --- python-jsonschema-3.2.0/json/tests/draft6/definitions.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/definitions.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,6 +1,6 @@ [ { - "description": "valid definition", + "description": "validate definition against metaschema", "schema": {"$ref": "http://json-schema.org/draft-06/schema#"}, "tests": [ { @@ -11,13 +11,7 @@ } }, "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "http://json-schema.org/draft-06/schema#"}, - "tests": [ + }, { "description": "invalid definition schema", "data": { diff -Nru python-jsonschema-3.2.0/json/tests/draft6/dependencies.json python-jsonschema-4.6.0/json/tests/draft6/dependencies.json --- python-jsonschema-3.2.0/json/tests/draft6/dependencies.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/dependencies.json 2022-06-01 20:26:26.000000000 +0000 @@ -57,6 +57,11 @@ "description": "object with one property", "data": {"bar": 2}, "valid": true + }, + { + "description": "non-object is valid", + "data": 1, + "valid": true } ] }, @@ -168,31 +173,6 @@ "valid": true } ] - }, - { - "description": "empty array of dependencies", - "schema": { - "dependencies": { - "foo": [] - } - }, - "tests": [ - { - "description": "object with property is valid", - "data": { "foo": 1 }, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "non-object is valid", - "data": 1, - "valid": true - } - ] }, { "description": "dependencies with escaped characters", diff -Nru python-jsonschema-3.2.0/json/tests/draft6/enum.json python-jsonschema-4.6.0/json/tests/draft6/enum.json --- python-jsonschema-3.2.0/json/tests/draft6/enum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -33,6 +33,37 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false } ] }, @@ -53,6 +84,16 @@ "valid": true }, { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true @@ -175,5 +216,21 @@ "valid": true } ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/format.json python-jsonschema-4.6.0/json/tests/draft6/format.json --- python-jsonschema-3.2.0/json/tests/draft6/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,323 +1,323 @@ [ { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "description": "email format", + "schema": { "format": "email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "description": "ipv4 format", + "schema": { "format": "ipv4" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "description": "ipv6 format", + "schema": { "format": "ipv6" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of hostnames", - "schema": {"format": "hostname"}, + "description": "hostname format", + "schema": { "format": "hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "description": "date-time format", + "schema": { "format": "date-time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of JSON pointers", - "schema": {"format": "json-pointer"}, + "description": "json-pointer format", + "schema": { "format": "json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URIs", - "schema": {"format": "uri"}, + "description": "uri format", + "schema": { "format": "uri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI references", - "schema": {"format": "uri-reference"}, + "description": "uri-reference format", + "schema": { "format": "uri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI templates", - "schema": {"format": "uri-template"}, + "description": "uri-template format", + "schema": { "format": "uri-template" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } diff -Nru python-jsonschema-3.2.0/json/tests/draft6/id.json python-jsonschema-4.6.0/json/tests/draft6/id.json --- python-jsonschema-3.2.0/json/tests/draft6/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,53 @@ +[ + { + "description": "id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an id buried in the enum", + "schema": { + "definitions": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/definitions/id_in_enum" }, + { "$ref": "https://localhost:1234/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to id", + "data": "a string to match #/definitions/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to id", + "data": 1, + "valid": false + } + ] + } + +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft6/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft6/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "definitions": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/definitions/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/definitions/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/maximum.json python-jsonschema-4.6.0/json/tests/draft6/maximum.json --- python-jsonschema-3.2.0/json/tests/draft6/maximum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -24,5 +24,31 @@ "valid": true } ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/maxProperties.json python-jsonschema-4.6.0/json/tests/draft6/maxProperties.json --- python-jsonschema-3.2.0/json/tests/draft6/maxProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -34,5 +34,21 @@ "valid": true } ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/minimum.json python-jsonschema-4.6.0/json/tests/draft6/minimum.json --- python-jsonschema-3.2.0/json/tests/draft6/minimum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,7 +45,17 @@ "valid": true }, { - "description": "below the minimum is invalid", + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", "data": -3, "valid": false }, diff -Nru python-jsonschema-3.2.0/json/tests/draft6/multipleOf.json python-jsonschema-4.6.0/json/tests/draft6/multipleOf.json --- python-jsonschema-3.2.0/json/tests/draft6/multipleOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/oneOf.json python-jsonschema-4.6.0/json/tests/draft6/oneOf.json --- python-jsonschema-3.2.0/json/tests/draft6/oneOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -202,5 +202,73 @@ "valid": false } ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": true, + "baz": true + }, + "required": ["bar"] + }, + { + "properties": { + "foo": true + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/bignum.json python-jsonschema-4.6.0/json/tests/draft6/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/bignum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,30 +1,13 @@ [ { "description": "integer", - "schema": {"type": "integer"}, + "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ + }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, @@ -34,9 +17,14 @@ }, { "description": "number", - "schema": {"type": "number"}, + "schema": { "type": "number" }, "tests": [ { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true @@ -45,7 +33,7 @@ }, { "description": "string", - "schema": {"type": "string"}, + "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", @@ -56,7 +44,7 @@ }, { "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, + "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", @@ -80,7 +68,7 @@ }, { "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, + "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/draft6/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/ecmascript-regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", @@ -19,7 +8,7 @@ "tests": [ { "description": "matches in Python, but should not in jsonschema", - "data": "abc\n", + "data": "abc\\n", "valid": false }, { @@ -30,20 +19,20 @@ ] }, { - "description": "ECMA 262 regex converts \\a to ascii BEL", + "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", - "pattern": "^\\a$" + "pattern": "^\\t$" }, "tests": [ { "description": "does not match", - "data": "\\a", + "data": "\\t", "valid": false }, { "description": "matches", - "data": "\u0007", + "data": "\u0009", "valid": true } ] @@ -154,7 +143,7 @@ ] }, { - "description": "ECMA 262 \\w matches everything but ascii letters", + "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" @@ -173,7 +162,7 @@ ] }, { - "description": "ECMA 262 \\s matches ascii whitespace only", + "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" @@ -185,14 +174,59 @@ "valid": true }, { - "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", "valid": false } ] }, { - "description": "ECMA 262 \\S matches everything but ascii whitespace", + "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" @@ -204,8 +238,313 @@ "valid": false }, { - "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/draft6/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/date-time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,133 @@ +[ + { + "description": "validation of date-time strings", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "a valid date-time string without second fraction", + "data": "1963-06-19T08:30:06Z", + "valid": true + }, + { + "description": "a valid date-time string with plus offset", + "data": "1937-01-01T12:00:27.87+00:20", + "valid": true + }, + { + "description": "a valid date-time string with minus offset", + "data": "1990-12-31T15:59:50.123-08:00", + "valid": true + }, + { + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", + "valid": false + }, + { + "description": "an invalid offset in date-time string", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", + "valid": false + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "case-insensitive T and Z", + "data": "1963-06-19t08:30:06.283185z", + "valid": true + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,83 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": { "format": "email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/hostname.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,98 @@ +[ + { + "description": "validation of host names", + "schema": { "format": "hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a valid punycoded IDN hostname", + "data": "xn--4gbwdl.xn--wgbh1c", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/ipv4.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,84 @@ +[ + { + "description": "validation of IP addresses", + "schema": { "format": "ipv4" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/ipv6.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,208 @@ +[ + { + "description": "validation of IPv6 addresses", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/json-pointer.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/json-pointer.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,198 @@ +[ + { + "description": "validation of JSON-pointers (JSON String Representation)", + "schema": { "format": "json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid JSON-pointer", + "data": "/foo/bar~0/baz~1/%a", + "valid": true + }, + { + "description": "not a valid JSON-pointer (~ not escaped)", + "data": "/foo/bar~", + "valid": false + }, + { + "description": "valid JSON-pointer with empty segment", + "data": "/foo//bar", + "valid": true + }, + { + "description": "valid JSON-pointer with the last empty segment", + "data": "/foo/bar/", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #1", + "data": "", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #2", + "data": "/foo", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #3", + "data": "/foo/0", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #4", + "data": "/", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #5", + "data": "/a~1b", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #6", + "data": "/c%d", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #7", + "data": "/e^f", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #8", + "data": "/g|h", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #9", + "data": "/i\\j", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #10", + "data": "/k\"l", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #11", + "data": "/ ", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #12", + "data": "/m~0n", + "valid": true + }, + { + "description": "valid JSON-pointer used adding to the last array position", + "data": "/foo/-", + "valid": true + }, + { + "description": "valid JSON-pointer (- used as object member name)", + "data": "/foo/-/bar", + "valid": true + }, + { + "description": "valid JSON-pointer (multiple escaped characters)", + "data": "/~1~0~0~1~1", + "valid": true + }, + { + "description": "valid JSON-pointer (escaped with fraction part) #1", + "data": "/~1.1", + "valid": true + }, + { + "description": "valid JSON-pointer (escaped with fraction part) #2", + "data": "/~0.1", + "valid": true + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", + "data": "#", + "valid": false + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", + "data": "#/", + "valid": false + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", + "data": "#a", + "valid": false + }, + { + "description": "not a valid JSON-pointer (some escaped, but not all) #1", + "data": "/~0~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (some escaped, but not all) #2", + "data": "/~0/~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (wrong escape character) #1", + "data": "/~2", + "valid": false + }, + { + "description": "not a valid JSON-pointer (wrong escape character) #2", + "data": "/~-1", + "valid": false + }, + { + "description": "not a valid JSON-pointer (multiple characters not escaped)", + "data": "/~~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", + "data": "a", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", + "data": "0", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", + "data": "a/a", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/unknown.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/unknown.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/unknown.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/unknown.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,43 @@ +[ + { + "description": "unknown format", + "schema": { "format": "unknown" }, + "tests": [ + { + "description": "unknown formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "unknown formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "unknown formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "unknown formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "unknown formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "unknown formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "unknown formats ignore strings", + "data": "string", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/uri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,108 @@ +[ + { + "description": "validation of URIs", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "a valid URL with anchor tag", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid URL with anchor tag and parentheses", + "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", + "valid": true + }, + { + "description": "a valid URL with URL-encoded stuff", + "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", + "valid": true + }, + { + "description": "a valid puny-coded URL ", + "data": "http://xn--nw2a.xn--j6w193g/", + "valid": true + }, + { + "description": "a valid URL with many special characters", + "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", + "valid": true + }, + { + "description": "a valid URL based on IPv4", + "data": "http://223.255.255.254", + "valid": true + }, + { + "description": "a valid URL with ftp scheme", + "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", + "valid": true + }, + { + "description": "a valid URL for a simple text file", + "data": "http://www.ietf.org/rfc/rfc2396.txt", + "valid": true + }, + { + "description": "a valid URL ", + "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", + "valid": true + }, + { + "description": "a valid mailto URI", + "data": "mailto:John.Doe@example.com", + "valid": true + }, + { + "description": "a valid newsgroup URI", + "data": "news:comp.infosystems.www.servers.unix", + "valid": true + }, + { + "description": "a valid tel URI", + "data": "tel:+1-816-555-1212", + "valid": true + }, + { + "description": "a valid URN", + "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", + "valid": true + }, + { + "description": "an invalid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": false + }, + { + "description": "an invalid relative URI Reference", + "data": "/abc", + "valid": false + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + }, + { + "description": "an invalid URI with spaces", + "data": "http:// shouldfail.com", + "valid": false + }, + { + "description": "an invalid URI with spaces and missing scheme", + "data": ":// should fail", + "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/uri-reference.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/uri-reference.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/uri-reference.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/uri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,73 @@ +[ + { + "description": "validation of URI References", + "schema": { "format": "uri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid relative URI Reference", + "data": "/abc", + "valid": true + }, + { + "description": "an invalid URI Reference", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "a valid URI Reference", + "data": "abc", + "valid": true + }, + { + "description": "a valid URI fragment", + "data": "#fragment", + "valid": true + }, + { + "description": "an invalid URI fragment", + "data": "#frag\\ment", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format/uri-template.json python-jsonschema-4.6.0/json/tests/draft6/optional/format/uri-template.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format/uri-template.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format/uri-template.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,58 @@ +[ + { + "description": "format: uri-template", + "schema": { "format": "uri-template" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid uri-template", + "data": "http://example.com/dictionary/{term:1}/{term}", + "valid": true + }, + { + "description": "an invalid uri-template", + "data": "http://example.com/dictionary/{term:1}/{term", + "valid": false + }, + { + "description": "a valid uri-template without variables", + "data": "http://example.com/dictionary", + "valid": true + }, + { + "description": "a valid relative uri-template", + "data": "dictionary/{term:1}/{term}", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/format.json python-jsonschema-4.6.0/json/tests/draft6/optional/format.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/format.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,491 +0,0 @@ -[ - { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, - "tests": [ - { - "description": "a valid date-time string", - "data": "1963-06-19T08:30:06.283185Z", - "valid": true - }, - { - "description": "a valid date-time string without second fraction", - "data": "1963-06-19T08:30:06Z", - "valid": true - }, - { - "description": "a valid date-time string with plus offset", - "data": "1937-01-01T12:00:27.87+00:20", - "valid": true - }, - { - "description": "a valid date-time string with minus offset", - "data": "1990-12-31T15:59:50.123-08:00", - "valid": true - }, - { - "description": "a invalid day in date-time string", - "data": "1990-02-31T15:59:60.123-08:00", - "valid": false - }, - { - "description": "an invalid offset in date-time string", - "data": "1990-12-31T15:59:60-24:00", - "valid": false - }, - { - "description": "an invalid closing Z after time-zone offset", - "data": "1963-06-19T08:30:06.28123+01:00Z", - "valid": false - }, - { - "description": "an invalid date-time string", - "data": "06/19/1963 08:30:06 PST", - "valid": false - }, - { - "description": "case-insensitive T and Z", - "data": "1963-06-19t08:30:06.283185z", - "valid": true - }, - { - "description": "only RFC3339 not all of ISO 8601 are valid", - "data": "2013-350T01:01:01", - "valid": false - } - ] - }, - { - "description": "validation of URIs", - "schema": {"format": "uri"}, - "tests": [ - { - "description": "a valid URL with anchor tag", - "data": "http://foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "a valid URL with anchor tag and parantheses", - "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", - "valid": true - }, - { - "description": "a valid URL with URL-encoded stuff", - "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", - "valid": true - }, - { - "description": "a valid puny-coded URL ", - "data": "http://xn--nw2a.xn--j6w193g/", - "valid": true - }, - { - "description": "a valid URL with many special characters", - "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", - "valid": true - }, - { - "description": "a valid URL based on IPv4", - "data": "http://223.255.255.254", - "valid": true - }, - { - "description": "a valid URL with ftp scheme", - "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", - "valid": true - }, - { - "description": "a valid URL for a simple text file", - "data": "http://www.ietf.org/rfc/rfc2396.txt", - "valid": true - }, - { - "description": "a valid URL ", - "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", - "valid": true - }, - { - "description": "a valid mailto URI", - "data": "mailto:John.Doe@example.com", - "valid": true - }, - { - "description": "a valid newsgroup URI", - "data": "news:comp.infosystems.www.servers.unix", - "valid": true - }, - { - "description": "a valid tel URI", - "data": "tel:+1-816-555-1212", - "valid": true - }, - { - "description": "a valid URN", - "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", - "valid": true - }, - { - "description": "an invalid protocol-relative URI Reference", - "data": "//foo.bar/?baz=qux#quux", - "valid": false - }, - { - "description": "an invalid relative URI Reference", - "data": "/abc", - "valid": false - }, - { - "description": "an invalid URI", - "data": "\\\\WINDOWS\\fileshare", - "valid": false - }, - { - "description": "an invalid URI though valid URI reference", - "data": "abc", - "valid": false - }, - { - "description": "an invalid URI with spaces", - "data": "http:// shouldfail.com", - "valid": false - }, - { - "description": "an invalid URI with spaces and missing scheme", - "data": ":// should fail", - "valid": false - } - ] - }, - { - "description": "validation of URI References", - "schema": {"format": "uri-reference"}, - "tests": [ - { - "description": "a valid URI", - "data": "http://foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "a valid protocol-relative URI Reference", - "data": "//foo.bar/?baz=qux#quux", - "valid": true - }, - { - "description": "a valid relative URI Reference", - "data": "/abc", - "valid": true - }, - { - "description": "an invalid URI Reference", - "data": "\\\\WINDOWS\\fileshare", - "valid": false - }, - { - "description": "a valid URI Reference", - "data": "abc", - "valid": true - }, - { - "description": "a valid URI fragment", - "data": "#fragment", - "valid": true - }, - { - "description": "an invalid URI fragment", - "data": "#frag\\ment", - "valid": false - } - ] - }, - { - "description": "format: uri-template", - "schema": {"format": "uri-template"}, - "tests": [ - { - "description": "a valid uri-template", - "data": "http://example.com/dictionary/{term:1}/{term}", - "valid": true - }, - { - "description": "an invalid uri-template", - "data": "http://example.com/dictionary/{term:1}/{term", - "valid": false - }, - { - "description": "a valid uri-template without variables", - "data": "http://example.com/dictionary", - "valid": true - }, - { - "description": "a valid relative uri-template", - "data": "dictionary/{term:1}/{term}", - "valid": true - } - ] - }, - { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, - "tests": [ - { - "description": "a valid e-mail address", - "data": "joe.bloggs@example.com", - "valid": true - }, - { - "description": "an invalid e-mail address", - "data": "2962", - "valid": false - } - ] - }, - { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, - "tests": [ - { - "description": "a valid IP address", - "data": "192.168.0.1", - "valid": true - }, - { - "description": "an IP address with too many components", - "data": "127.0.0.0.1", - "valid": false - }, - { - "description": "an IP address with out-of-range values", - "data": "256.256.256.256", - "valid": false - }, - { - "description": "an IP address without 4 components", - "data": "127.0", - "valid": false - }, - { - "description": "an IP address as an integer", - "data": "0x7f000001", - "valid": false - } - ] - }, - { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, - "tests": [ - { - "description": "a valid IPv6 address", - "data": "::1", - "valid": true - }, - { - "description": "an IPv6 address with out-of-range values", - "data": "12345::", - "valid": false - }, - { - "description": "an IPv6 address with too many components", - "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", - "valid": false - }, - { - "description": "an IPv6 address containing illegal characters", - "data": "::laptop", - "valid": false - } - ] - }, - { - "description": "validation of host names", - "schema": {"format": "hostname"}, - "tests": [ - { - "description": "a valid host name", - "data": "www.example.com", - "valid": true - }, - { - "description": "a host name starting with an illegal character", - "data": "-a-host-name-that-starts-with--", - "valid": false - }, - { - "description": "a host name containing illegal characters", - "data": "not_a_valid_host_name", - "valid": false - }, - { - "description": "a host name with a component too long", - "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", - "valid": false - } - ] - }, - { - "description": "validation of JSON-pointers (JSON String Representation)", - "schema": {"format": "json-pointer"}, - "tests": [ - { - "description": "a valid JSON-pointer", - "data": "/foo/bar~0/baz~1/%a", - "valid": true - }, - { - "description": "not a valid JSON-pointer (~ not escaped)", - "data": "/foo/bar~", - "valid": false - }, - { - "description": "valid JSON-pointer with empty segment", - "data": "/foo//bar", - "valid": true - }, - { - "description": "valid JSON-pointer with the last empty segment", - "data": "/foo/bar/", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #1", - "data": "", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #2", - "data": "/foo", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #3", - "data": "/foo/0", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #4", - "data": "/", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #5", - "data": "/a~1b", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #6", - "data": "/c%d", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #7", - "data": "/e^f", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #8", - "data": "/g|h", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #9", - "data": "/i\\j", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #10", - "data": "/k\"l", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #11", - "data": "/ ", - "valid": true - }, - { - "description": "valid JSON-pointer as stated in RFC 6901 #12", - "data": "/m~0n", - "valid": true - }, - { - "description": "valid JSON-pointer used adding to the last array position", - "data": "/foo/-", - "valid": true - }, - { - "description": "valid JSON-pointer (- used as object member name)", - "data": "/foo/-/bar", - "valid": true - }, - { - "description": "valid JSON-pointer (multiple escaped characters)", - "data": "/~1~0~0~1~1", - "valid": true - }, - { - "description": "valid JSON-pointer (escaped with fraction part) #1", - "data": "/~1.1", - "valid": true - }, - { - "description": "valid JSON-pointer (escaped with fraction part) #2", - "data": "/~0.1", - "valid": true - }, - { - "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", - "data": "#", - "valid": false - }, - { - "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", - "data": "#/", - "valid": false - }, - { - "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", - "data": "#a", - "valid": false - }, - { - "description": "not a valid JSON-pointer (some escaped, but not all) #1", - "data": "/~0~", - "valid": false - }, - { - "description": "not a valid JSON-pointer (some escaped, but not all) #2", - "data": "/~0/~", - "valid": false - }, - { - "description": "not a valid JSON-pointer (wrong escape character) #1", - "data": "/~2", - "valid": false - }, - { - "description": "not a valid JSON-pointer (wrong escape character) #2", - "data": "/~-1", - "valid": false - }, - { - "description": "not a valid JSON-pointer (multiple characters not escaped)", - "data": "/~~", - "valid": false - }, - { - "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", - "data": "a", - "valid": false - }, - { - "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", - "data": "0", - "valid": false - }, - { - "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", - "data": "a/a", - "valid": false - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft6/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/optional/zeroTerminatedFloats.json python-jsonschema-4.6.0/json/tests/draft6/optional/zeroTerminatedFloats.json --- python-jsonschema-3.2.0/json/tests/draft6/optional/zeroTerminatedFloats.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/optional/zeroTerminatedFloats.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -[ - { - "description": "some languages do not distinguish between different types of numeric value", - "schema": { - "type": "integer" - }, - "tests": [ - { - "description": "a float without fractional part is an integer", - "data": 1.0, - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/pattern.json python-jsonschema-4.6.0/json/tests/draft6/pattern.json --- python-jsonschema-3.2.0/json/tests/draft6/pattern.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,9 +14,34 @@ "valid": false }, { - "description": "ignores non-strings", + "description": "ignores booleans", "data": true, "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true } ] }, diff -Nru python-jsonschema-3.2.0/json/tests/draft6/patternProperties.json python-jsonschema-4.6.0/json/tests/draft6/patternProperties.json --- python-jsonschema-3.2.0/json/tests/draft6/patternProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/patternProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -142,6 +142,11 @@ "valid": false }, { + "description": "object with a property matching both true and false is invalid", + "data": {"foobar":1}, + "valid": false + }, + { "description": "empty object is valid", "data": {}, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft6/propertyNames.json python-jsonschema-4.6.0/json/tests/draft6/propertyNames.json --- python-jsonschema-3.2.0/json/tests/draft6/propertyNames.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/propertyNames.json 2022-06-01 20:26:26.000000000 +0000 @@ -44,6 +44,35 @@ ] }, { + "description": "propertyNames validation with pattern", + "schema": { + "propertyNames": { "pattern": "^a+$" } + }, + "tests": [ + { + "description": "matching property names valid", + "data": { + "a": {}, + "aa": {}, + "aaa": {} + }, + "valid": true + }, + { + "description": "non-matching property name is invalid", + "data": { + "aaA": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + } + ] + }, + { "description": "propertyNames with boolean schema true", "schema": {"propertyNames": true}, "tests": [ diff -Nru python-jsonschema-3.2.0/json/tests/draft6/ref.json python-jsonschema-4.6.0/json/tests/draft6/ref.json --- python-jsonschema-3.2.0/json/tests/draft6/ref.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ @@ -91,8 +93,8 @@ "valid": false }, { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, "valid": false }, { @@ -106,8 +108,8 @@ "valid": true }, { - "description": "tilda valid", - "data": {"tilda": 123}, + "description": "tilde valid", + "data": {"tilde": 123}, "valid": true }, { @@ -125,7 +127,7 @@ "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, - "$ref": "#/definitions/c" + "allOf": [{ "$ref": "#/definitions/c" }] }, "tests": [ { @@ -174,6 +176,42 @@ ] }, { + "description": "$ref prevents a sibling $id from changing the base uri", + "schema": { + "$id": "http://localhost:1234/sibling_id/base/", + "definitions": { + "foo": { + "$id": "http://localhost:1234/sibling_id/foo.json", + "type": "string" + }, + "base_foo": { + "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", + "$id": "foo.json", + "type": "number" + } + }, + "allOf": [ + { + "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", + "$id": "http://localhost:1234/sibling_id/", + "$ref": "foo.json" + } + ] + }, + "tests": [ + { + "description": "$ref resolves to /definitions/base_foo, data does not validate", + "data": "a", + "valid": false + }, + { + "description": "$ref resolves to /definitions/base_foo, data validates", + "data": 1, + "valid": true + } + ] + }, + { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-06/schema#"}, "tests": [ @@ -210,9 +248,34 @@ ] }, { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/definitions/is-string"} + }, + "definitions": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { "description": "$ref to boolean schema true", "schema": { - "$ref": "#/definitions/bool", + "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": true } @@ -228,7 +291,7 @@ { "description": "$ref to boolean schema false", "schema": { - "$ref": "#/definitions/bool", + "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": false } @@ -383,15 +446,21 @@ ] }, { - "description": "Location-independent identifier with absolute URI", + "description": "Location-independent identifier with base URI change in subschema", "schema": { + "$id": "http://localhost:1234/root", "allOf": [{ - "$ref": "http://localhost:1234/bar#foo" + "$ref": "http://localhost:1234/nested.json#foo" }], "definitions": { "A": { - "$id": "http://localhost:1234/bar#foo", - "type": "integer" + "$id": "nested.json", + "definitions": { + "B": { + "$id": "#foo", + "type": "integer" + } + } } } }, @@ -409,34 +478,134 @@ ] }, { - "description": "Location-independent identifier with base URI change in subschema", + "description": "naive replacement of $ref with its destination is not correct", "schema": { - "$id": "http://localhost:1234/root", - "allOf": [{ - "$ref": "http://localhost:1234/nested.json#foo" - }], "definitions": { - "A": { - "$id": "nested.json", + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/definitions/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "do not evaluate the $ref inside the enum, definition exact match", + "data": { "type": "string" }, + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/definitions/a_string" }, + "valid": true + } + ] + }, + { + "description": "refs with relative uris and defs", + "schema": { + "$id": "http://example.com/schema-relative-uri-defs1.json", + "properties": { + "foo": { + "$id": "schema-relative-uri-defs2.json", "definitions": { - "B": { - "$id": "#foo", - "type": "integer" + "inner": { + "properties": { + "bar": { "type": "string" } + } } - } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] } - } + }, + "allOf": [ { "$ref": "schema-relative-uri-defs2.json" } ] }, "tests": [ { - "data": 1, - "description": "match", + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, "valid": true + } + ] + }, + { + "description": "relative refs with absolute uris and defs", + "schema": { + "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", + "properties": { + "foo": { + "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", + "definitions": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] + } }, + "allOf": [ { "$ref": "schema-refs-absolute-uris-defs2.json" } ] + }, + "tests": [ { - "data": "a", - "description": "mismatch", + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft6/refRemote.json python-jsonschema-4.6.0/json/tests/draft6/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft6/refRemote.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -54,7 +54,7 @@ "schema": { "$id": "http://localhost:1234/", "items": { - "$id": "folder/", + "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, @@ -81,7 +81,7 @@ }, "definitions": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } @@ -110,7 +110,7 @@ }, "definitions": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolderInSubschema/", "definitions": { "bar": { "type": "array", @@ -167,5 +167,30 @@ "valid": false } ] + }, + { + "description": "remote ref with ref to definitions", + "schema": { + "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", + "allOf": [ + { "$ref": "ref-and-definitions.json" } + ] + }, + "tests": [ + { + "description": "invalid", + "data": { + "bar": 1 + }, + "valid": false + }, + { + "description": "valid", + "data": { + "bar": "a" + }, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft6/type.json python-jsonschema-4.6.0/json/tests/draft6/type.json --- python-jsonschema-3.2.0/json/tests/draft6/type.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -9,6 +9,11 @@ "valid": true }, { + "description": "a float with zero fractional part is an integer", + "data": 1.0, + "valid": true + }, + { "description": "a float is not an integer", "data": 1.1, "valid": false @@ -55,6 +60,11 @@ "valid": true }, { + "description": "a float with zero fractional part is a number (and an integer)", + "data": 1.0, + "valid": true + }, + { "description": "a float is a number", "data": 1.1, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft6/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft6/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft6/uniqueItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,6 +14,11 @@ "valid": false }, { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false @@ -29,6 +34,16 @@ "valid": true }, { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true @@ -65,6 +80,11 @@ "valid": false }, { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { "description": "1 and true are unique", "data": [1, true], "valid": true @@ -75,21 +95,61 @@ "valid": true }, { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], + "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], + "items": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ @@ -138,8 +198,8 @@ { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], - "uniqueItems": true, + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, "additionalItems": false }, "tests": [ @@ -165,6 +225,177 @@ }, { "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft6/unknownKeyword.json python-jsonschema-4.6.0/json/tests/draft6/unknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft6/unknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft6/unknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,56 @@ +[ + { + "description": "$id inside an unknown keyword is not a real identifier", + "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", + "schema": { + "definitions": { + "id_in_unknown0": { + "not": { + "array_of_schemas": [ + { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "null" + } + ] + } + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "string" + }, + "id_in_unknown1": { + "not": { + "object_of_schemas": { + "foo": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "integer" + } + } + } + } + }, + "anyOf": [ + { "$ref": "#/definitions/id_in_unknown0" }, + { "$ref": "#/definitions/id_in_unknown1" }, + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "type matches second anyOf, which has a real schema in it", + "data": "a string", + "valid": true + }, + { + "description": "type matches non-schema in first anyOf", + "data": null, + "valid": false + }, + { + "description": "type matches non-schema in third anyOf", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/additionalItems.json python-jsonschema-4.6.0/json/tests/draft7/additionalItems.json --- python-jsonschema-3.2.0/json/tests/draft7/additionalItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/additionalItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -19,7 +19,7 @@ ] }, { - "description": "items is schema, no additionalItems", + "description": "when items is schema, additionalItems does nothing", "schema": { "items": {}, "additionalItems": false @@ -33,14 +33,24 @@ ] }, { - "description": "array of items with no additionalItems", + "description": "array of items with no additionalItems permitted", "schema": { "items": [{}, {}, {}], "additionalItems": false }, "tests": [ { - "description": "fewer number of items present", + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", "data": [ 1, 2 ], "valid": true }, @@ -83,5 +93,57 @@ "valid": true } ] + }, + { + "description": "additionalItems should not look in applicators, valid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" } ] } + ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, null ], + "valid": true + } + ] + }, + { + "description": "additionalItems should not look in applicators, invalid case", + "schema": { + "allOf": [ + { "items": [ { "type": "integer" }, { "type": "string" } ] } + ], + "items": [ {"type": "integer" } ], + "additionalItems": { "type": "boolean" } + }, + "tests": [ + { + "description": "items defined in allOf are not examined", + "data": [ 1, "hello" ], + "valid": false + } + ] + }, + { + "description": "items validation adjusts the starting index for additionalItems", + "schema": { + "items": [ { "type": "string" } ], + "additionalItems": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft7/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft7/additionalProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -124,7 +124,7 @@ }, "tests": [ { - "description": "properties defined in allOf are not allowed", + "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/allOf.json python-jsonschema-4.6.0/json/tests/draft7/allOf.json --- python-jsonschema-3.2.0/json/tests/draft7/allOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -214,5 +214,81 @@ "valid": false } ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/anyOf.json python-jsonschema-4.6.0/json/tests/draft7/anyOf.json --- python-jsonschema-3.2.0/json/tests/draft7/anyOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/anyOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -185,5 +185,31 @@ "valid": false } ] + }, + { + "description": "nested anyOf, to check validation semantics", + "schema": { + "anyOf": [ + { + "anyOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/const.json python-jsonschema-4.6.0/json/tests/draft7/const.json --- python-jsonschema-3.2.0/json/tests/draft7/const.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/const.json 2022-06-01 20:26:26.000000000 +0000 @@ -126,7 +126,91 @@ ] }, { - "description": "const with 0 does not match false", + "description": "const with [false] does not match [0]", + "schema": {"const": [false]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, + { + "description": "const with [true] does not match [1]", + "schema": {"const": [true]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, + { + "description": "const with {\"a\": false} does not match {\"a\": 0}", + "schema": {"const": {"a": false}}, + "tests": [ + { + "description": "{\"a\": false} is valid", + "data": {"a": false}, + "valid": true + }, + { + "description": "{\"a\": 0} is invalid", + "data": {"a": 0}, + "valid": false + }, + { + "description": "{\"a\": 0.0} is invalid", + "data": {"a": 0.0}, + "valid": false + } + ] + }, + { + "description": "const with {\"a\": true} does not match {\"a\": 1}", + "schema": {"const": {"a": true}}, + "tests": [ + { + "description": "{\"a\": true} is valid", + "data": {"a": true}, + "valid": true + }, + { + "description": "{\"a\": 1} is invalid", + "data": {"a": 1}, + "valid": false + }, + { + "description": "{\"a\": 1.0} is invalid", + "data": {"a": 1.0}, + "valid": false + } + ] + }, + { + "description": "const with 0 does not match other zero-like types", "schema": {"const": 0}, "tests": [ { @@ -143,6 +227,21 @@ "description": "float zero is valid", "data": 0.0, "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "empty string is invalid", + "data": "", + "valid": false } ] }, @@ -166,5 +265,78 @@ "valid": true } ] + }, + { + "description": "const with -2.0 matches integer and float types", + "schema": {"const": -2.0}, + "tests": [ + { + "description": "integer -2 is valid", + "data": -2, + "valid": true + }, + { + "description": "integer 2 is invalid", + "data": 2, + "valid": false + }, + { + "description": "float -2.0 is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float 2.0 is invalid", + "data": 2.0, + "valid": false + }, + { + "description": "float -2.00001 is invalid", + "data": -2.00001, + "valid": false + } + ] + }, + { + "description": "float and integers are equal up to 64-bit representation limits", + "schema": {"const": 9007199254740992}, + "tests": [ + { + "description": "integer is valid", + "data": 9007199254740992, + "valid": true + }, + { + "description": "integer minus one is invalid", + "data": 9007199254740991, + "valid": false + }, + { + "description": "float is valid", + "data": 9007199254740992.0, + "valid": true + }, + { + "description": "float minus one is invalid", + "data": 9007199254740991.0, + "valid": false + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "const": "hello\u0000there" }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/contains.json python-jsonschema-4.6.0/json/tests/draft7/contains.json --- python-jsonschema-3.2.0/json/tests/draft7/contains.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/contains.json 2022-06-01 20:26:26.000000000 +0000 @@ -96,5 +96,55 @@ "valid": true } ] + }, + { + "description": "items + contains", + "schema": { + "items": { "multipleOf": 2 }, + "contains": { "multipleOf": 3 } + }, + "tests": [ + { + "description": "matches items, does not match contains", + "data": [ 2, 4, 8 ], + "valid": false + }, + { + "description": "does not match items, matches contains", + "data": [ 3, 6, 9 ], + "valid": false + }, + { + "description": "matches both items and contains", + "data": [ 6, 12 ], + "valid": true + }, + { + "description": "matches neither items nor contains", + "data": [ 1, 5 ], + "valid": false + } + ] + }, + { + "description": "contains with false if subschema", + "schema": { + "contains": { + "if": false, + "else": true + } + }, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/default.json python-jsonschema-4.6.0/json/tests/draft7/default.json --- python-jsonschema-3.2.0/json/tests/draft7/default.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,5 +45,35 @@ "valid": true } ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/definitions.json python-jsonschema-4.6.0/json/tests/draft7/definitions.json --- python-jsonschema-3.2.0/json/tests/draft7/definitions.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/definitions.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,6 +1,6 @@ [ { - "description": "valid definition", + "description": "validate definition against metaschema", "schema": {"$ref": "http://json-schema.org/draft-07/schema#"}, "tests": [ { @@ -11,13 +11,7 @@ } }, "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "http://json-schema.org/draft-07/schema#"}, - "tests": [ + }, { "description": "invalid definition schema", "data": { diff -Nru python-jsonschema-3.2.0/json/tests/draft7/dependencies.json python-jsonschema-4.6.0/json/tests/draft7/dependencies.json --- python-jsonschema-3.2.0/json/tests/draft7/dependencies.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/dependencies.json 2022-06-01 20:26:26.000000000 +0000 @@ -57,6 +57,11 @@ "description": "object with one property", "data": {"bar": 2}, "valid": true + }, + { + "description": "non-object is valid", + "data": 1, + "valid": true } ] }, @@ -168,31 +173,6 @@ "valid": true } ] - }, - { - "description": "empty array of dependencies", - "schema": { - "dependencies": { - "foo": [] - } - }, - "tests": [ - { - "description": "object with property is valid", - "data": { "foo": 1 }, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "non-object is valid", - "data": 1, - "valid": true - } - ] }, { "description": "dependencies with escaped characters", diff -Nru python-jsonschema-3.2.0/json/tests/draft7/enum.json python-jsonschema-4.6.0/json/tests/draft7/enum.json --- python-jsonschema-3.2.0/json/tests/draft7/enum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -33,6 +33,37 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false } ] }, @@ -53,6 +84,16 @@ "valid": true }, { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true @@ -175,5 +216,21 @@ "valid": true } ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/format.json python-jsonschema-4.6.0/json/tests/draft7/format.json --- python-jsonschema-3.2.0/json/tests/draft7/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,611 +1,611 @@ [ { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "description": "email format", + "schema": { "format": "email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IDN e-mail addresses", - "schema": {"format": "idn-email"}, + "description": "idn-email format", + "schema": { "format": "idn-email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of regexes", - "schema": {"format": "regex"}, + "description": "regex format", + "schema": { "format": "regex" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "description": "ipv4 format", + "schema": { "format": "ipv4" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "description": "ipv6 format", + "schema": { "format": "ipv6" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IDN hostnames", - "schema": {"format": "idn-hostname"}, + "description": "idn-hostname format", + "schema": { "format": "idn-hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of hostnames", - "schema": {"format": "hostname"}, + "description": "hostname format", + "schema": { "format": "hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date strings", - "schema": {"format": "date"}, + "description": "date format", + "schema": { "format": "date" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "description": "date-time format", + "schema": { "format": "date-time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of time strings", - "schema": {"format": "time"}, + "description": "time format", + "schema": { "format": "time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of JSON pointers", - "schema": {"format": "json-pointer"}, + "description": "json-pointer format", + "schema": { "format": "json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of relative JSON pointers", - "schema": {"format": "relative-json-pointer"}, + "description": "relative-json-pointer format", + "schema": { "format": "relative-json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IRIs", - "schema": {"format": "iri"}, + "description": "iri format", + "schema": { "format": "iri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IRI references", - "schema": {"format": "iri-reference"}, + "description": "iri-reference format", + "schema": { "format": "iri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URIs", - "schema": {"format": "uri"}, + "description": "uri format", + "schema": { "format": "uri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI references", - "schema": {"format": "uri-reference"}, + "description": "uri-reference format", + "schema": { "format": "uri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI templates", - "schema": {"format": "uri-template"}, + "description": "uri-template format", + "schema": { "format": "uri-template" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/id.json python-jsonschema-4.6.0/json/tests/draft7/id.json --- python-jsonschema-3.2.0/json/tests/draft7/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,53 @@ +[ + { + "description": "id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an id buried in the enum", + "schema": { + "definitions": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/definitions/id_in_enum" }, + { "$ref": "https://localhost:1234/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to id", + "data": "a string to match #/definitions/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to id", + "data": 1, + "valid": false + } + ] + } + +] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/if-then-else.json python-jsonschema-4.6.0/json/tests/draft7/if-then-else.json --- python-jsonschema-3.2.0/json/tests/draft7/if-then-else.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/if-then-else.json 2022-06-01 20:26:26.000000000 +0000 @@ -184,5 +184,75 @@ "valid": true } ] + }, + { + "description": "if with boolean schema true", + "schema": { + "if": true, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema true in if always chooses the then path (valid)", + "data": "then", + "valid": true + }, + { + "description": "boolean schema true in if always chooses the then path (invalid)", + "data": "else", + "valid": false + } + ] + }, + { + "description": "if with boolean schema false", + "schema": { + "if": false, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema false in if always chooses the else path (invalid)", + "data": "then", + "valid": false + }, + { + "description": "boolean schema false in if always chooses the else path (valid)", + "data": "else", + "valid": true + } + ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft7/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft7/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "definitions": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/definitions/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/definitions/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/maximum.json python-jsonschema-4.6.0/json/tests/draft7/maximum.json --- python-jsonschema-3.2.0/json/tests/draft7/maximum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -24,5 +24,31 @@ "valid": true } ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/maxProperties.json python-jsonschema-4.6.0/json/tests/draft7/maxProperties.json --- python-jsonschema-3.2.0/json/tests/draft7/maxProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -34,5 +34,21 @@ "valid": true } ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/minimum.json python-jsonschema-4.6.0/json/tests/draft7/minimum.json --- python-jsonschema-3.2.0/json/tests/draft7/minimum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,7 +45,17 @@ "valid": true }, { - "description": "below the minimum is invalid", + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", "data": -3, "valid": false }, diff -Nru python-jsonschema-3.2.0/json/tests/draft7/multipleOf.json python-jsonschema-4.6.0/json/tests/draft7/multipleOf.json --- python-jsonschema-3.2.0/json/tests/draft7/multipleOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/oneOf.json python-jsonschema-4.6.0/json/tests/draft7/oneOf.json --- python-jsonschema-3.2.0/json/tests/draft7/oneOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -202,5 +202,73 @@ "valid": false } ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": true, + "baz": true + }, + "required": ["bar"] + }, + { + "properties": { + "foo": true + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/bignum.json python-jsonschema-4.6.0/json/tests/draft7/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/bignum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,30 +1,13 @@ [ { "description": "integer", - "schema": {"type": "integer"}, + "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ + }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, @@ -34,9 +17,14 @@ }, { "description": "number", - "schema": {"type": "number"}, + "schema": { "type": "number" }, "tests": [ { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true @@ -45,7 +33,7 @@ }, { "description": "string", - "schema": {"type": "string"}, + "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", @@ -56,7 +44,7 @@ }, { "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, + "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", @@ -80,7 +68,7 @@ }, { "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, + "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/draft7/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/ecmascript-regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", @@ -19,7 +8,7 @@ "tests": [ { "description": "matches in Python, but should not in jsonschema", - "data": "abc\n", + "data": "abc\\n", "valid": false }, { @@ -30,20 +19,20 @@ ] }, { - "description": "ECMA 262 regex converts \\a to ascii BEL", + "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", - "pattern": "^\\a$" + "pattern": "^\\t$" }, "tests": [ { "description": "does not match", - "data": "\\a", + "data": "\\t", "valid": false }, { "description": "matches", - "data": "\u0007", + "data": "\u0009", "valid": true } ] @@ -154,7 +143,7 @@ ] }, { - "description": "ECMA 262 \\w matches everything but ascii letters", + "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" @@ -173,7 +162,7 @@ ] }, { - "description": "ECMA 262 \\s matches ascii whitespace only", + "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" @@ -185,14 +174,59 @@ "valid": true }, { - "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", "valid": false } ] }, { - "description": "ECMA 262 \\S matches everything but ascii whitespace", + "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" @@ -204,8 +238,313 @@ "valid": false }, { - "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/draft7/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/date.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/date.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/date.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/date.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,180 @@ [ { "description": "validation of date strings", - "schema": {"format": "date"}, + "schema": { "format": "date" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { - "description": "an invalid date-time string", + "description": "a valid date string with 31 days in January", + "data": "2020-01-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in January", + "data": "2020-01-32", + "valid": false + }, + { + "description": "a valid date string with 28 days in February (normal)", + "data": "2021-02-28", + "valid": true + }, + { + "description": "a invalid date string with 29 days in February (normal)", + "data": "2021-02-29", + "valid": false + }, + { + "description": "a valid date string with 29 days in February (leap)", + "data": "2020-02-29", + "valid": true + }, + { + "description": "a invalid date string with 30 days in February (leap)", + "data": "2020-02-30", + "valid": false + }, + { + "description": "a valid date string with 31 days in March", + "data": "2020-03-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in March", + "data": "2020-03-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in April", + "data": "2020-04-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in April", + "data": "2020-04-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in May", + "data": "2020-05-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in May", + "data": "2020-05-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in June", + "data": "2020-06-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in June", + "data": "2020-06-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in July", + "data": "2020-07-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in July", + "data": "2020-07-32", + "valid": false + }, + { + "description": "a valid date string with 31 days in August", + "data": "2020-08-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in August", + "data": "2020-08-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in September", + "data": "2020-09-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in September", + "data": "2020-09-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in October", + "data": "2020-10-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in October", + "data": "2020-10-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in November", + "data": "2020-11-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in November", + "data": "2020-11-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in December", + "data": "2020-12-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in December", + "data": "2020-12-32", + "valid": false + }, + { + "description": "a invalid date string with invalid month", + "data": "2020-13-01", + "valid": false + }, + { + "description": "an invalid date string", "data": "06/19/1963", "valid": false }, @@ -17,6 +182,41 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false + }, + { + "description": "non-padded month dates are not valid", + "data": "1998-1-20", + "valid": false + }, + { + "description": "non-padded day dates are not valid", + "data": "1998-01-1", + "valid": false + }, + { + "description": "invalid month", + "data": "1998-13-01", + "valid": false + }, + { + "description": "invalid month-day combination", + "data": "1998-04-31", + "valid": false + }, + { + "description": "2021 is not a leap year", + "data": "2021-02-29", + "valid": false + }, + { + "description": "2020 is a leap year", + "data": "2020-02-29", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1963-06-1৪", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/date-time.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "schema": { "format": "date-time" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true @@ -24,13 +54,43 @@ "valid": true }, { - "description": "a invalid day in date-time string", - "data": "1990-02-31T15:59:60.123-08:00", + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", - "data": "1990-12-31T15:59:60-24:00", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { @@ -47,6 +107,26 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/email.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "schema": { "format": "email" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true @@ -12,6 +42,41 @@ "description": "an invalid e-mail address", "data": "2962", "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/hostname.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of host names", - "schema": {"format": "hostname"}, + "schema": { "format": "hostname" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid host name", "data": "www.example.com", "valid": true @@ -27,6 +57,41 @@ "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/idn-email.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/idn-email.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/idn-email.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/idn-email.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of an internationalized e-mail addresses", - "schema": {"format": "idn-email"}, + "schema": { "format": "idn-email" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true @@ -12,6 +42,16 @@ "description": "an invalid idn e-mail address", "data": "2962", "valid": false + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/idn-hostname.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/idn-hostname.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/idn-hostname.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/idn-hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of internationalized host names", - "schema": {"format": "idn-hostname"}, + "schema": { "format": "idn-hostname" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true @@ -22,6 +52,252 @@ "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false + }, + { + "description": "invalid label, correct Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", + "data": "-> $1.00 <--", + "valid": false + }, + { + "description": "valid Chinese Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", + "data": "xn--ihqwcrb4cv8a8dqg056pqjye", + "valid": true + }, + { + "description": "invalid Punycode", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "xn--X", + "valid": false + }, + { + "description": "U-label contains \"--\" in the 3rd and 4th position", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "XN--aa---o47jg78q", + "valid": false + }, + { + "description": "U-label starts with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello", + "valid": false + }, + { + "description": "U-label ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "hello-", + "valid": false + }, + { + "description": "U-label starts and ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello-", + "valid": false + }, + { + "description": "Begins with a Spacing Combining Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0903hello", + "valid": false + }, + { + "description": "Begins with a Nonspacing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0300hello", + "valid": false + }, + { + "description": "Begins with an Enclosing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0488hello", + "valid": false + }, + { + "description": "Exceptions that are PVALID, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u00df\u03c2\u0f0b\u3007", + "valid": true + }, + { + "description": "Exceptions that are PVALID, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u06fd\u06fe", + "valid": true + }, + { + "description": "Exceptions that are DISALLOWED, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u0640\u07fa", + "valid": false + }, + { + "description": "Exceptions that are DISALLOWED, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", + "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", + "valid": false + }, + { + "description": "MIDDLE DOT with no preceding 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "a\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing preceding", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with no following 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7a", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing following", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7", + "valid": false + }, + { + "description": "MIDDLE DOT with surrounding 'l's", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7l", + "valid": true + }, + { + "description": "Greek KERAIA not followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375S", + "valid": false + }, + { + "description": "Greek KERAIA not followed by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375", + "valid": false + }, + { + "description": "Greek KERAIA followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375\u03b2", + "valid": true + }, + { + "description": "Hebrew GERESH not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "A\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05d0\u05f3\u05d1", + "valid": true + }, + { + "description": "Hebrew GERSHAYIM not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "A\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05d0\u05f4\u05d1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "def\u30fbabc", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with no other characters", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with Hiragana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u3041", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Katakana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u30a1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u4e08", + "valid": true + }, + { + "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0660\u06f0", + "valid": false + }, + { + "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0628\u0660\u0628", + "valid": true + }, + { + "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", + "data": "\u06f00", + "valid": true + }, + { + "description": "ZERO WIDTH JOINER not preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u094d\u200d\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", + "data": "\u0915\u094d\u200c\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", + "data": "\u0628\u064a\u200c\u0628\u064a", + "valid": true } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/ipv4.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "schema": { "format": "ipv4" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IP address", "data": "192.168.0.1", "valid": true @@ -27,6 +57,27 @@ "description": "an IP address as an integer", "data": "0x7f000001", "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/ipv6.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "schema": { "format": "ipv6" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IPv6 address", "data": "::1", "valid": true @@ -14,6 +44,16 @@ "valid": false }, { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false @@ -22,6 +62,146 @@ "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/iri.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/iri.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/iri.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/iri.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,45 @@ [ { "description": "validation of IRIs", - "schema": {"format": "iri"}, + "schema": { "format": "iri" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { - "description": "a valid IRI with anchor tag and parantheses", + "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/iri-reference.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/iri-reference.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/iri-reference.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/iri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IRI References", - "schema": {"format": "iri-reference"}, + "schema": { "format": "iri-reference" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/json-pointer.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/json-pointer.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of JSON-pointers (JSON String Representation)", - "schema": {"format": "json-pointer"}, + "schema": { "format": "json-pointer" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/regex.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/regex.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of regular expressions", - "schema": {"format": "regex"}, + "schema": { "format": "regex" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/relative-json-pointer.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/relative-json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/relative-json-pointer.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/relative-json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,45 @@ [ { "description": "validation of Relative JSON Pointers (RJP)", - "schema": {"format": "relative-json-pointer"}, + "schema": { "format": "relative-json-pointer" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid upwards RJP", "data": "1", "valid": true }, { - "description": "a valid downwards RJP", + "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, @@ -27,6 +57,26 @@ "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false + }, + { + "description": "negative prefix", + "data": "-1/foo/bar", + "valid": false + }, + { + "description": "## is not a valid json-pointer", + "data": "0##", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus json-pointer", + "data": "01/a", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus octothorpe", + "data": "01#", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/time.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/time.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/time.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/time.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,180 @@ [ { "description": "validation of time strings", - "schema": {"format": "time"}, + "schema": { "format": "time" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid time string", + "data": "08:30:06Z", + "valid": true + }, + { + "description": "a valid time string with leap second, Zulu", + "data": "23:59:60Z", + "valid": true + }, + { + "description": "invalid leap second, Zulu (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "invalid leap second, Zulu (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "valid leap second, zero time-offset", + "data": "23:59:60+00:00", + "valid": true + }, + { + "description": "invalid leap second, zero time-offset (wrong hour)", + "data": "22:59:60+00:00", + "valid": false + }, + { + "description": "invalid leap second, zero time-offset (wrong minute)", + "data": "23:58:60+00:00", + "valid": false + }, + { + "description": "valid leap second, positive time-offset", + "data": "01:29:60+01:30", + "valid": true + }, + { + "description": "valid leap second, large positive time-offset", + "data": "23:29:60+23:30", + "valid": true + }, + { + "description": "invalid leap second, positive time-offset (wrong hour)", + "data": "23:59:60+01:00", + "valid": false + }, + { + "description": "invalid leap second, positive time-offset (wrong minute)", + "data": "23:59:60+00:30", + "valid": false + }, + { + "description": "valid leap second, negative time-offset", + "data": "15:59:60-08:00", + "valid": true + }, + { + "description": "valid leap second, large negative time-offset", + "data": "00:29:60-23:30", + "valid": true + }, + { + "description": "invalid leap second, negative time-offset (wrong hour)", + "data": "23:59:60-01:00", + "valid": false + }, + { + "description": "invalid leap second, negative time-offset (wrong minute)", + "data": "23:59:60-00:30", + "valid": false + }, + { + "description": "a valid time string with second fraction", + "data": "23:20:50.52Z", + "valid": true + }, + { + "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { - "description": "an invalid time string", + "description": "a valid time string with plus offset", + "data": "08:30:06+00:20", + "valid": true + }, + { + "description": "a valid time string with minus offset", + "data": "08:30:06-08:00", + "valid": true + }, + { + "description": "a valid time string with case-insensitive Z", + "data": "08:30:06z", + "valid": true + }, + { + "description": "an invalid time string with invalid hour", + "data": "24:00:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid minute", + "data": "00:60:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid second", + "data": "00:00:61Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset hour", + "data": "01:02:03+24:00", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset minute", + "data": "01:02:03+00:60", + "valid": false + }, + { + "description": "an invalid time string with invalid time with both Z and numoffset", + "data": "01:02:03Z+00:30", + "valid": false + }, + { + "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, @@ -17,6 +182,16 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false + }, + { + "description": "no time offset", + "data": "12:00:00", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২:00:00Z", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/unknown.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/unknown.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/unknown.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/unknown.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,43 @@ +[ + { + "description": "unknown format", + "schema": { "format": "unknown" }, + "tests": [ + { + "description": "unknown formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "unknown formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "unknown formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "unknown formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "unknown formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "unknown formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "unknown formats ignore strings", + "data": "string", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/uri.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,7 +1,7 @@ [ { "description": "validation of URIs", - "schema": {"format": "uri"}, + "schema": { "format": "uri" }, "tests": [ { "description": "a valid URL with anchor tag", @@ -9,7 +9,7 @@ "valid": true }, { - "description": "a valid URL with anchor tag and parantheses", + "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, @@ -97,6 +97,11 @@ "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/uri-reference.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/uri-reference.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/uri-reference.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/uri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of URI References", - "schema": {"format": "uri-reference"}, + "schema": { "format": "uri-reference" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/format/uri-template.json python-jsonschema-4.6.0/json/tests/draft7/optional/format/uri-template.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/format/uri-template.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/format/uri-template.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "format: uri-template", - "schema": {"format": "uri-template"}, + "schema": { "format": "uri-template" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft7/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/optional/zeroTerminatedFloats.json python-jsonschema-4.6.0/json/tests/draft7/optional/zeroTerminatedFloats.json --- python-jsonschema-3.2.0/json/tests/draft7/optional/zeroTerminatedFloats.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/optional/zeroTerminatedFloats.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -[ - { - "description": "some languages do not distinguish between different types of numeric value", - "schema": { - "type": "integer" - }, - "tests": [ - { - "description": "a float without fractional part is an integer", - "data": 1.0, - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/pattern.json python-jsonschema-4.6.0/json/tests/draft7/pattern.json --- python-jsonschema-3.2.0/json/tests/draft7/pattern.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,9 +14,34 @@ "valid": false }, { - "description": "ignores non-strings", + "description": "ignores booleans", "data": true, "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true } ] }, diff -Nru python-jsonschema-3.2.0/json/tests/draft7/patternProperties.json python-jsonschema-4.6.0/json/tests/draft7/patternProperties.json --- python-jsonschema-3.2.0/json/tests/draft7/patternProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/patternProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -142,6 +142,11 @@ "valid": false }, { + "description": "object with a property matching both true and false is invalid", + "data": {"foobar":1}, + "valid": false + }, + { "description": "empty object is valid", "data": {}, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/propertyNames.json python-jsonschema-4.6.0/json/tests/draft7/propertyNames.json --- python-jsonschema-3.2.0/json/tests/draft7/propertyNames.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/propertyNames.json 2022-06-01 20:26:26.000000000 +0000 @@ -44,6 +44,35 @@ ] }, { + "description": "propertyNames validation with pattern", + "schema": { + "propertyNames": { "pattern": "^a+$" } + }, + "tests": [ + { + "description": "matching property names valid", + "data": { + "a": {}, + "aa": {}, + "aaa": {} + }, + "valid": true + }, + { + "description": "non-matching property name is invalid", + "data": { + "aaA": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + } + ] + }, + { "description": "propertyNames with boolean schema true", "schema": {"propertyNames": true}, "tests": [ diff -Nru python-jsonschema-3.2.0/json/tests/draft7/ref.json python-jsonschema-4.6.0/json/tests/draft7/ref.json --- python-jsonschema-3.2.0/json/tests/draft7/ref.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "definitions": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/definitions/tilde~0field"}, + "slash": {"$ref": "#/definitions/slash~1field"}, + "percent": {"$ref": "#/definitions/percent%25field"} } }, "tests": [ @@ -91,8 +93,8 @@ "valid": false }, { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, "valid": false }, { @@ -106,8 +108,8 @@ "valid": true }, { - "description": "tilda valid", - "data": {"tilda": 123}, + "description": "tilde valid", + "data": {"tilde": 123}, "valid": true }, { @@ -125,7 +127,7 @@ "b": {"$ref": "#/definitions/a"}, "c": {"$ref": "#/definitions/b"} }, - "$ref": "#/definitions/c" + "allOf": [{ "$ref": "#/definitions/c" }] }, "tests": [ { @@ -174,6 +176,42 @@ ] }, { + "description": "$ref prevents a sibling $id from changing the base uri", + "schema": { + "$id": "http://localhost:1234/sibling_id/base/", + "definitions": { + "foo": { + "$id": "http://localhost:1234/sibling_id/foo.json", + "type": "string" + }, + "base_foo": { + "$comment": "this canonical uri is http://localhost:1234/sibling_id/base/foo.json", + "$id": "foo.json", + "type": "number" + } + }, + "allOf": [ + { + "$comment": "$ref resolves to http://localhost:1234/sibling_id/base/foo.json, not http://localhost:1234/sibling_id/foo.json", + "$id": "http://localhost:1234/sibling_id/", + "$ref": "foo.json" + } + ] + }, + "tests": [ + { + "description": "$ref resolves to /definitions/base_foo, data does not validate", + "data": "a", + "valid": false + }, + { + "description": "$ref resolves to /definitions/base_foo, data validates", + "data": 1, + "valid": true + } + ] + }, + { "description": "remote ref, containing refs itself", "schema": {"$ref": "http://json-schema.org/draft-07/schema#"}, "tests": [ @@ -210,9 +248,34 @@ ] }, { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/definitions/is-string"} + }, + "definitions": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { "description": "$ref to boolean schema true", "schema": { - "$ref": "#/definitions/bool", + "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": true } @@ -228,7 +291,7 @@ { "description": "$ref to boolean schema false", "schema": { - "$ref": "#/definitions/bool", + "allOf": [{ "$ref": "#/definitions/bool" }], "definitions": { "bool": false } @@ -383,15 +446,21 @@ ] }, { - "description": "Location-independent identifier with absolute URI", + "description": "Location-independent identifier with base URI change in subschema", "schema": { + "$id": "http://localhost:1234/root", "allOf": [{ - "$ref": "http://localhost:1234/bar#foo" + "$ref": "http://localhost:1234/nested.json#foo" }], "definitions": { "A": { - "$id": "http://localhost:1234/bar#foo", - "type": "integer" + "$id": "nested.json", + "definitions": { + "B": { + "$id": "#foo", + "type": "integer" + } + } } } }, @@ -409,33 +478,169 @@ ] }, { - "description": "Location-independent identifier with base URI change in subschema", + "description": "naive replacement of $ref with its destination is not correct", "schema": { - "$id": "http://localhost:1234/root", - "allOf": [{ - "$ref": "http://localhost:1234/nested.json#foo" - }], "definitions": { - "A": { - "$id": "nested.json", + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/definitions/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "do not evaluate the $ref inside the enum, definition exact match", + "data": { "type": "string" }, + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/definitions/a_string" }, + "valid": true + } + ] + }, + { + "description": "refs with relative uris and defs", + "schema": { + "$id": "http://example.com/schema-relative-uri-defs1.json", + "properties": { + "foo": { + "$id": "schema-relative-uri-defs2.json", "definitions": { - "B": { - "$id": "#foo", - "type": "integer" + "inner": { + "properties": { + "bar": { "type": "string" } + } } - } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] } + }, + "allOf": [ { "$ref": "schema-relative-uri-defs2.json" } ] + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true } + ] + }, + { + "description": "relative refs with absolute uris and defs", + "schema": { + "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", + "properties": { + "foo": { + "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", + "definitions": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] + } + }, + "allOf": [ { "$ref": "schema-refs-absolute-uris-defs2.json" } ] }, "tests": [ { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "$id must be resolved against nearest parent, not just immediate parent", + "schema": { + "$id": "http://example.com/a.json", + "definitions": { + "x": { + "$id": "http://example.com/b/c.json", + "not": { + "definitions": { + "y": { + "$id": "d.json", + "type": "number" + } + } + } + } + }, + "allOf": [ + { + "$ref": "http://example.com/b/d.json" + } + ] + }, + "tests": [ + { + "description": "number should pass", "data": 1, - "description": "match", "valid": true }, { + "description": "non-number should fail", "data": "a", - "description": "mismatch", "valid": false } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/refRemote.json python-jsonschema-4.6.0/json/tests/draft7/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft7/refRemote.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -54,7 +54,7 @@ "schema": { "$id": "http://localhost:1234/", "items": { - "$id": "folder/", + "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, @@ -81,7 +81,7 @@ }, "definitions": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } @@ -110,7 +110,7 @@ }, "definitions": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolderInSubschema/", "definitions": { "bar": { "type": "array", @@ -167,5 +167,30 @@ "valid": false } ] + }, + { + "description": "remote ref with ref to definitions", + "schema": { + "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", + "allOf": [ + { "$ref": "ref-and-definitions.json" } + ] + }, + "tests": [ + { + "description": "invalid", + "data": { + "bar": 1 + }, + "valid": false + }, + { + "description": "valid", + "data": { + "bar": "a" + }, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/draft7/type.json python-jsonschema-4.6.0/json/tests/draft7/type.json --- python-jsonschema-3.2.0/json/tests/draft7/type.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -9,6 +9,11 @@ "valid": true }, { + "description": "a float with zero fractional part is an integer", + "data": 1.0, + "valid": true + }, + { "description": "a float is not an integer", "data": 1.1, "valid": false @@ -55,6 +60,11 @@ "valid": true }, { + "description": "a float with zero fractional part is a number (and an integer)", + "data": 1.0, + "valid": true + }, + { "description": "a float is a number", "data": 1.1, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/draft7/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft7/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft7/uniqueItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,6 +14,11 @@ "valid": false }, { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false @@ -29,6 +34,16 @@ "valid": true }, { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true @@ -65,6 +80,11 @@ "valid": false }, { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { "description": "1 and true are unique", "data": [1, true], "valid": true @@ -75,14 +95,54 @@ "valid": true }, { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], + "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true } ] }, @@ -165,6 +225,177 @@ }, { "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "items": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "additionalItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/draft7/unknownKeyword.json python-jsonschema-4.6.0/json/tests/draft7/unknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft7/unknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft7/unknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,56 @@ +[ + { + "description": "$id inside an unknown keyword is not a real identifier", + "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", + "schema": { + "definitions": { + "id_in_unknown0": { + "not": { + "array_of_schemas": [ + { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "null" + } + ] + } + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "string" + }, + "id_in_unknown1": { + "not": { + "object_of_schemas": { + "foo": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "integer" + } + } + } + } + }, + "anyOf": [ + { "$ref": "#/definitions/id_in_unknown0" }, + { "$ref": "#/definitions/id_in_unknown1" }, + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "type matches second anyOf, which has a real schema in it", + "data": "a string", + "valid": true + }, + { + "description": "type matches non-schema in first anyOf", + "data": null, + "valid": false + }, + { + "description": "type matches non-schema in third anyOf", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/additionalProperties.json python-jsonschema-4.6.0/json/tests/draft-next/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/draft-next/additionalProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,133 @@ +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobarbaz", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": "non-ASCII pattern with additionalProperties", + "schema": { + "patternProperties": {"^á": {}}, + "additionalProperties": false + }, + "tests": [ + { + "description": "matching the pattern is valid", + "data": {"ármányos": 2}, + "valid": true + }, + { + "description": "not matching the pattern is invalid", + "data": {"élmény": 2}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + }, + { + "description": "additionalProperties should not look in applicators", + "schema": { + "allOf": [ + {"properties": {"foo": {}}} + ], + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "properties defined in allOf are not examined", + "data": {"foo": 1, "bar": true}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/allOf.json python-jsonschema-4.6.0/json/tests/draft-next/allOf.json --- python-jsonschema-3.2.0/json/tests/draft-next/allOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,294 @@ +[ + { + "description": "allOf", + "schema": { + "allOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "allOf", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch second", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch first", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "allOf with base schema", + "schema": { + "properties": {"bar": {"type": "integer"}}, + "required": ["bar"], + "allOf" : [ + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + }, + { + "properties": { + "baz": {"type": "null"} + }, + "required": ["baz"] + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch base schema", + "data": {"foo": "quux", "baz": null}, + "valid": false + }, + { + "description": "mismatch first allOf", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second allOf", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "allOf simple types", + "schema": { + "allOf": [ + {"maximum": 30}, + {"minimum": 20} + ] + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch one", + "data": 35, + "valid": false + } + ] + }, + { + "description": "allOf with boolean schemas, all true", + "schema": {"allOf": [true, true]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "allOf with boolean schemas, some false", + "schema": {"allOf": [true, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "allOf with boolean schemas, all false", + "schema": {"allOf": [false, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "allOf with one empty schema", + "schema": { + "allOf": [ + {} + ] + }, + "tests": [ + { + "description": "any data is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "allOf with two empty schemas", + "schema": { + "allOf": [ + {}, + {} + ] + }, + "tests": [ + { + "description": "any data is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "allOf with the first empty schema", + "schema": { + "allOf": [ + {}, + { "type": "number" } + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "allOf with the last empty schema", + "schema": { + "allOf": [ + { "type": "number" }, + {} + ] + }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/anchor.json python-jsonschema-4.6.0/json/tests/draft-next/anchor.json --- python-jsonschema-3.2.0/json/tests/draft-next/anchor.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/anchor.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,173 @@ +[ + { + "description": "Location-independent identifier", + "schema": { + "$ref": "#foo", + "$defs": { + "A": { + "$anchor": "foo", + "type": "integer" + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "Location-independent identifier with absolute URI", + "schema": { + "$ref": "http://localhost:1234/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar", + "$anchor": "foo", + "type": "integer" + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "Location-independent identifier with base URI change in subschema", + "schema": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$anchor": "foo", + "type": "integer" + } + } + } + } + }, + "tests": [ + { + "data": 1, + "description": "match", + "valid": true + }, + { + "data": "a", + "description": "mismatch", + "valid": false + } + ] + }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, + { + "description": "same $anchor with different base uri", + "schema": { + "$id": "http://localhost:1234/foobar", + "$defs": { + "A": { + "$id": "child1", + "allOf": [ + { + "$id": "child2", + "$anchor": "my_anchor", + "type": "number" + }, + { + "$anchor": "my_anchor", + "type": "string" + } + ] + } + }, + "$ref": "child1#my_anchor" + }, + "tests": [ + { + "description": "$ref should resolve to /$defs/A/allOf/1", + "data": "a", + "valid": true + }, + { + "description": "$ref should not resolve to /$defs/A/allOf/0", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/anyOf.json python-jsonschema-4.6.0/json/tests/draft-next/anyOf.json --- python-jsonschema-3.2.0/json/tests/draft-next/anyOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/anyOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,189 @@ +[ + { + "description": "anyOf", + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first anyOf valid", + "data": 1, + "valid": true + }, + { + "description": "second anyOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both anyOf valid", + "data": 3, + "valid": true + }, + { + "description": "neither anyOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "anyOf with base schema", + "schema": { + "type": "string", + "anyOf" : [ + { + "maxLength": 2 + }, + { + "minLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one anyOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both anyOf invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "anyOf with boolean schemas, all true", + "schema": {"anyOf": [true, true]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "anyOf with boolean schemas, some true", + "schema": {"anyOf": [true, false]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "anyOf with boolean schemas, all false", + "schema": {"anyOf": [false, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "anyOf complex types", + "schema": { + "anyOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first anyOf valid (complex)", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "second anyOf valid (complex)", + "data": {"foo": "baz"}, + "valid": true + }, + { + "description": "both anyOf valid (complex)", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "neither anyOf valid (complex)", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "anyOf with one empty schema", + "schema": { + "anyOf": [ + { "type": "number" }, + {} + ] + }, + "tests": [ + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "number is valid", + "data": 123, + "valid": true + } + ] + }, + { + "description": "nested anyOf, to check validation semantics", + "schema": { + "anyOf": [ + { + "anyOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/boolean_schema.json python-jsonschema-4.6.0/json/tests/draft-next/boolean_schema.json --- python-jsonschema-3.2.0/json/tests/draft-next/boolean_schema.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/boolean_schema.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,104 @@ +[ + { + "description": "boolean schema 'true'", + "schema": true, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "boolean schema 'false'", + "schema": false, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/const.json python-jsonschema-4.6.0/json/tests/draft-next/const.json --- python-jsonschema-3.2.0/json/tests/draft-next/const.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/const.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,342 @@ +[ + { + "description": "const validation", + "schema": {"const": 2}, + "tests": [ + { + "description": "same value is valid", + "data": 2, + "valid": true + }, + { + "description": "another value is invalid", + "data": 5, + "valid": false + }, + { + "description": "another type is invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "const with object", + "schema": {"const": {"foo": "bar", "baz": "bax"}}, + "tests": [ + { + "description": "same object is valid", + "data": {"foo": "bar", "baz": "bax"}, + "valid": true + }, + { + "description": "same object with different property order is valid", + "data": {"baz": "bax", "foo": "bar"}, + "valid": true + }, + { + "description": "another object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "another type is invalid", + "data": [1, 2], + "valid": false + } + ] + }, + { + "description": "const with array", + "schema": {"const": [{ "foo": "bar" }]}, + "tests": [ + { + "description": "same array is valid", + "data": [{"foo": "bar"}], + "valid": true + }, + { + "description": "another array item is invalid", + "data": [2], + "valid": false + }, + { + "description": "array with additional items is invalid", + "data": [1, 2, 3], + "valid": false + } + ] + }, + { + "description": "const with null", + "schema": {"const": null}, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "not null is invalid", + "data": 0, + "valid": false + } + ] + }, + { + "description": "const with false does not match 0", + "schema": {"const": false}, + "tests": [ + { + "description": "false is valid", + "data": false, + "valid": true + }, + { + "description": "integer zero is invalid", + "data": 0, + "valid": false + }, + { + "description": "float zero is invalid", + "data": 0.0, + "valid": false + } + ] + }, + { + "description": "const with true does not match 1", + "schema": {"const": true}, + "tests": [ + { + "description": "true is valid", + "data": true, + "valid": true + }, + { + "description": "integer one is invalid", + "data": 1, + "valid": false + }, + { + "description": "float one is invalid", + "data": 1.0, + "valid": false + } + ] + }, + { + "description": "const with [false] does not match [0]", + "schema": {"const": [false]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, + { + "description": "const with [true] does not match [1]", + "schema": {"const": [true]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, + { + "description": "const with {\"a\": false} does not match {\"a\": 0}", + "schema": {"const": {"a": false}}, + "tests": [ + { + "description": "{\"a\": false} is valid", + "data": {"a": false}, + "valid": true + }, + { + "description": "{\"a\": 0} is invalid", + "data": {"a": 0}, + "valid": false + }, + { + "description": "{\"a\": 0.0} is invalid", + "data": {"a": 0.0}, + "valid": false + } + ] + }, + { + "description": "const with {\"a\": true} does not match {\"a\": 1}", + "schema": {"const": {"a": true}}, + "tests": [ + { + "description": "{\"a\": true} is valid", + "data": {"a": true}, + "valid": true + }, + { + "description": "{\"a\": 1} is invalid", + "data": {"a": 1}, + "valid": false + }, + { + "description": "{\"a\": 1.0} is invalid", + "data": {"a": 1.0}, + "valid": false + } + ] + }, + { + "description": "const with 0 does not match other zero-like types", + "schema": {"const": 0}, + "tests": [ + { + "description": "false is invalid", + "data": false, + "valid": false + }, + { + "description": "integer zero is valid", + "data": 0, + "valid": true + }, + { + "description": "float zero is valid", + "data": 0.0, + "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "empty string is invalid", + "data": "", + "valid": false + } + ] + }, + { + "description": "const with 1 does not match true", + "schema": {"const": 1}, + "tests": [ + { + "description": "true is invalid", + "data": true, + "valid": false + }, + { + "description": "integer one is valid", + "data": 1, + "valid": true + }, + { + "description": "float one is valid", + "data": 1.0, + "valid": true + } + ] + }, + { + "description": "const with -2.0 matches integer and float types", + "schema": {"const": -2.0}, + "tests": [ + { + "description": "integer -2 is valid", + "data": -2, + "valid": true + }, + { + "description": "integer 2 is invalid", + "data": 2, + "valid": false + }, + { + "description": "float -2.0 is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float 2.0 is invalid", + "data": 2.0, + "valid": false + }, + { + "description": "float -2.00001 is invalid", + "data": -2.00001, + "valid": false + } + ] + }, + { + "description": "float and integers are equal up to 64-bit representation limits", + "schema": {"const": 9007199254740992}, + "tests": [ + { + "description": "integer is valid", + "data": 9007199254740992, + "valid": true + }, + { + "description": "integer minus one is invalid", + "data": 9007199254740991, + "valid": false + }, + { + "description": "float is valid", + "data": 9007199254740992.0, + "valid": true + }, + { + "description": "float minus one is invalid", + "data": 9007199254740991.0, + "valid": false + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "const": "hello\u0000there" }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/contains.json python-jsonschema-4.6.0/json/tests/draft-next/contains.json --- python-jsonschema-3.2.0/json/tests/draft-next/contains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/contains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,241 @@ +[ + { + "description": "contains keyword validation", + "schema": { + "contains": { "minimum": 5 } + }, + "tests": [ + { + "description": "array with item matching schema (5) is valid", + "data": [3, 4, 5], + "valid": true + }, + { + "description": "array with item matching schema (6) is valid", + "data": [3, 4, 6], + "valid": true + }, + { + "description": "array with two items matching schema (5, 6) is valid", + "data": [3, 4, 5, 6], + "valid": true + }, + { + "description": "array without items matching schema is invalid", + "data": [2, 3, 4], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "object with property matching schema (5) is valid", + "data": { "a": 3, "b": 4, "c": 5 }, + "valid": true + }, + { + "description": "object with property matching schema (6) is valid", + "data": { "a": 3, "b": 4, "c": 6 }, + "valid": true + }, + { + "description": "object with two properties matching schema (5, 6) is valid", + "data": { "a": 3, "b": 4, "c": 5, "d": 6 }, + "valid": true + }, + { + "description": "object without properties matching schema is invalid", + "data": { "a": 2, "b": 3, "c": 4 }, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "not array or object is valid", + "data": 42, + "valid": true + } + ] + }, + { + "description": "contains keyword with const keyword", + "schema": { + "contains": { "const": 5 } + }, + "tests": [ + { + "description": "array with item 5 is valid", + "data": [3, 4, 5], + "valid": true + }, + { + "description": "array with two items 5 is valid", + "data": [3, 4, 5, 5], + "valid": true + }, + { + "description": "array without item 5 is invalid", + "data": [1, 2, 3, 4], + "valid": false + }, + { + "description": "object with property 5 is valid", + "data": { "a": 3, "b": 4, "c": 5 }, + "valid": true + }, + { + "description": "object with two properties 5 is valid", + "data": { "a": 3, "b": 4, "c": 5, "d": 5 }, + "valid": true + }, + { + "description": "object without property 5 is invalid", + "data": { "a": 1, "b": 2, "c": 3, "d": 4 }, + "valid": false + } + ] + }, + { + "description": "contains keyword with boolean schema true", + "schema": { "contains": true }, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "any non-empty object is valid", + "data": { "a": "foo" }, + "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + } + ] + }, + { + "description": "contains keyword with boolean schema false", + "schema": { "contains": false }, + "tests": [ + { + "description": "any non-empty array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "any non-empty object is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "non-arrays/objects are valid", + "data": "contains does not apply to strings", + "valid": true + } + ] + }, + { + "description": "items + contains", + "schema": { + "additionalProperties": { "multipleOf": 2 }, + "items": { "multipleOf": 2 }, + "contains": { "multipleOf": 3 } + }, + "tests": [ + { + "description": "matches items, does not match contains", + "data": [2, 4, 8], + "valid": false + }, + { + "description": "does not match items, matches contains", + "data": [3, 6, 9], + "valid": false + }, + { + "description": "matches both items and contains", + "data": [6, 12], + "valid": true + }, + { + "description": "matches neither items nor contains", + "data": [1, 5], + "valid": false + }, + { + "description": "matches additionalProperties, does not match contains", + "data": { "a": 2, "b": 4, "c": 8 }, + "valid": false + }, + { + "description": "does not match additionalProperties, matches contains", + "data": { "a": 3, "b": 6, "c": 9 }, + "valid": false + }, + { + "description": "matches both additionalProperties and contains", + "data": { "a": 6, "b": 12 }, + "valid": true + }, + { + "description": "matches neither additionalProperties nor contains", + "data": { "a": 1, "b": 5 }, + "valid": false + } + ] + }, + { + "description": "contains with false if subschema", + "schema": { + "contains": { + "if": false, + "else": true + } + }, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "any non-empty object is valid", + "data": { "a": "foo" }, + "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/content.json python-jsonschema-4.6.0/json/tests/draft-next/content.json --- python-jsonschema-3.2.0/json/tests/draft-next/content.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/content.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,127 @@ +[ + { + "description": "validation of string-encoded content based on media type", + "schema": { + "contentMediaType": "application/json" + }, + "tests": [ + { + "description": "a valid JSON document", + "data": "{\"foo\": \"bar\"}", + "valid": true + }, + { + "description": "an invalid JSON document; validates true", + "data": "{:}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary string-encoding", + "schema": { + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64 string", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "an invalid base64 string (% is not a valid character); validates true", + "data": "eyJmb28iOi%iYmFyIn0K", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents with schema", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64", + "contentSchema": { "required": ["foo"], "properties": { "foo": { "type": "string" } } } + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "another valid base64-encoded JSON document", + "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", + "valid": true + }, + { + "description": "an invalid base64-encoded JSON document; validates true", + "data": "eyJib28iOiAyMH0=", + "valid": true + }, + { + "description": "an empty object as a base64-encoded JSON document; validates true", + "data": "e30=", + "valid": true + }, + { + "description": "an empty array as a base64-encoded JSON document", + "data": "W10=", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/default.json python-jsonschema-4.6.0/json/tests/draft-next/default.json --- python-jsonschema-3.2.0/json/tests/draft-next/default.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,79 @@ +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/defs.json python-jsonschema-4.6.0/json/tests/draft-next/defs.json --- python-jsonschema-3.2.0/json/tests/draft-next/defs.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/defs.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,20 @@ +[ + { + "description": "validate definition against metaschema", + "schema": { + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "valid definition schema", + "data": {"$defs": {"foo": {"type": "integer"}}}, + "valid": true + }, + { + "description": "invalid definition schema", + "data": {"$defs": {"foo": {"type": 1}}}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/dependentRequired.json python-jsonschema-4.6.0/json/tests/draft-next/dependentRequired.json --- python-jsonschema-3.2.0/json/tests/draft-next/dependentRequired.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/dependentRequired.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,142 @@ +[ + { + "description": "single dependency", + "schema": {"dependentRequired": {"bar": ["foo"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "empty dependents", + "schema": {"dependentRequired": {"bar": []}}, + "tests": [ + { + "description": "empty object", + "data": {}, + "valid": true + }, + { + "description": "object with one property", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "non-object is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "multiple dependents required", + "schema": {"dependentRequired": {"quux": ["foo", "bar"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentRequired": { + "foo\nbar": ["foo\rbar"], + "foo\"bar": ["foo'bar"] + } + }, + "tests": [ + { + "description": "CRLF", + "data": { + "foo\nbar": 1, + "foo\rbar": 2 + }, + "valid": true + }, + { + "description": "quoted quotes", + "data": { + "foo'bar": 1, + "foo\"bar": 2 + }, + "valid": true + }, + { + "description": "CRLF missing dependent", + "data": { + "foo\nbar": 1, + "foo": 2 + }, + "valid": false + }, + { + "description": "quoted quotes missing dependent", + "data": { + "foo\"bar": 2 + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/dependentSchemas.json python-jsonschema-4.6.0/json/tests/draft-next/dependentSchemas.json --- python-jsonschema-3.2.0/json/tests/draft-next/dependentSchemas.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/dependentSchemas.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,129 @@ +[ + { + "description": "single dependency", + "schema": { + "dependentSchemas": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "boolean subschemas", + "schema": { + "dependentSchemas": { + "foo": true, + "bar": false + } + }, + "tests": [ + { + "description": "object with property having schema true is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property having schema false is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "object with both properties is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentSchemas": { + "foo\tbar": {"minProperties": 4}, + "foo'bar": {"required": ["foo\"bar"]} + } + }, + "tests": [ + { + "description": "quoted tab", + "data": { + "foo\tbar": 1, + "a": 2, + "b": 3, + "c": 4 + }, + "valid": true + }, + { + "description": "quoted quote", + "data": { + "foo'bar": {"foo\"bar": 1} + }, + "valid": false + }, + { + "description": "quoted tab invalid under dependent schema", + "data": { + "foo\tbar": 1, + "a": 2 + }, + "valid": false + }, + { + "description": "quoted quote invalid under dependent schema", + "data": {"foo'bar": 1}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/dynamicRef.json python-jsonschema-4.6.0/json/tests/draft-next/dynamicRef.json --- python-jsonschema-3.2.0/json/tests/draft-next/dynamicRef.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/dynamicRef.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,476 @@ +[ + { + "description": "A $dynamicRef to a $dynamicAnchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $ref to a $dynamicAnchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root", + "type": "array", + "items": { "$ref": "#items" }, + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef should resolve to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated", + "schema": { + "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" } + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor should not affect dynamic scope resolution", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root", + "$ref": "intermediate-scope", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "intermediate-scope": { + "$id": "intermediate-scope", + "$ref": "list" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" } + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "An $anchor with the same name as a $dynamicAnchor should not be used for dynamic scope resolution", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root", + "$ref": "list", + "$defs": { + "foo": { + "$anchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor should resolve to the first $dynamicAnchor in the dynamic scope", + "schema": { + "$id": "https://test.json-schema.org/relative-dynamic-reference/root", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "foo": { "const": "pass" } + }, + "$ref": "extended", + "$defs": { + "extended": { + "$id": "extended", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "bar": { "$ref": "bar" } + } + }, + "bar": { + "$id": "bar", + "type": "object", + "properties": { + "baz": { "$dynamicRef": "extended#meta" } + } + } + } + }, + "tests": [ + { + "description": "The recursive part is valid against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "pass" } + } + }, + "valid": true + }, + { + "description": "The recursive part is not valid against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "fail" } + } + }, + "valid": false + } + ] + }, + { + "description": "multiple dynamic paths to the $dynamicRef keyword", + "schema": { + "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main", + "$defs": { + "inner": { + "$id": "inner", + "$dynamicAnchor": "foo", + "title": "inner", + "additionalProperties": { + "$dynamicRef": "#foo" + } + } + }, + "if": { + "propertyNames": { + "pattern": "^[a-m]" + } + }, + "then": { + "title": "any type of node", + "$id": "anyLeafNode", + "$dynamicAnchor": "foo", + "$ref": "inner" + }, + "else": { + "title": "integer node", + "$id": "integerNode", + "$dynamicAnchor": "foo", + "type": [ "object", "integer" ], + "$ref": "inner" + } + }, + "tests": [ + { + "description": "recurse to anyLeafNode - floats are allowed", + "data": { "alpha": 1.1 }, + "valid": true + }, + { + "description": "recurse to integerNode - floats are not allowed", + "data": { "november": 1.1 }, + "valid": false + } + ] + }, + { + "description": "after leaving a dynamic scope, it should not be used by a $dynamicRef", + "schema": { + "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", + "if": { + "$id": "first_scope", + "$defs": { + "thingy": { + "$comment": "this is first_scope#thingy", + "$dynamicAnchor": "thingy", + "type": "number" + } + } + }, + "then": { + "$id": "second_scope", + "$ref": "start", + "$defs": { + "thingy": { + "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", + "$dynamicAnchor": "thingy", + "type": "null" + } + } + }, + "$defs": { + "start": { + "$comment": "this is the landing spot from $ref", + "$id": "start", + "$dynamicRef": "inner_scope#thingy" + }, + "thingy": { + "$comment": "this is the first stop for the $dynamicRef", + "$id": "inner_scope", + "$dynamicAnchor": "thingy", + "type": "string" + } + } + }, + "tests": [ + { + "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here", + "data": "a string", + "valid": false + }, + { + "description": "first_scope is not in dynamic scope for the $dynamicRef", + "data": 42, + "valid": false + }, + { + "description": "/then/$defs/thingy is the final stop for the $dynamicRef", + "data": null, + "valid": true + } + ] + }, + { + "description": "strict-tree schema, guards against misspelled properties", + "schema": { + "$id": "http://localhost:1234/strict-tree.json", + "$dynamicAnchor": "node", + + "$ref": "tree.json", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "instance with misspelled field", + "data": { + "children": [{ + "daat": 1 + }] + }, + "valid": false + }, + { + "description": "instance with correct field", + "data": { + "children": [{ + "data": 1 + }] + }, + "valid": true + } + ] + }, + { + "description": "tests for implementation dynamic anchor and reference link", + "schema": { + "$id": "http://localhost:1234/strict-extendible.json", + "$ref": "extendible-dynamic-ref.json", + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + }, + { + "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.", + "schema": { + "$id": "http://localhost:1234/strict-extendible-allof-defs-first.json", + "allOf": [ + { + "$ref": "extendible-dynamic-ref.json" + }, + { + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + } + ] + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + }, + { + "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.", + "schema": { + "$id": "http://localhost:1234/strict-extendible-allof-ref-first.json", + "allOf": [ + { + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + }, + { + "$ref": "extendible-dynamic-ref.json" + } + ] + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/enum.json python-jsonschema-4.6.0/json/tests/draft-next/enum.json --- python-jsonschema-3.2.0/json/tests/draft-next/enum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,236 @@ +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"]} + }, + "required": ["bar"] + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + }, + { + "description": "enum with escaped characters", + "schema": { + "enum": ["foo\nbar", "foo\rbar"] + }, + "tests": [ + { + "description": "member 1 is valid", + "data": "foo\nbar", + "valid": true + }, + { + "description": "member 2 is valid", + "data": "foo\rbar", + "valid": true + }, + { + "description": "another string is invalid", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "enum with false does not match 0", + "schema": {"enum": [false]}, + "tests": [ + { + "description": "false is valid", + "data": false, + "valid": true + }, + { + "description": "integer zero is invalid", + "data": 0, + "valid": false + }, + { + "description": "float zero is invalid", + "data": 0.0, + "valid": false + } + ] + }, + { + "description": "enum with true does not match 1", + "schema": {"enum": [true]}, + "tests": [ + { + "description": "true is valid", + "data": true, + "valid": true + }, + { + "description": "integer one is invalid", + "data": 1, + "valid": false + }, + { + "description": "float one is invalid", + "data": 1.0, + "valid": false + } + ] + }, + { + "description": "enum with 0 does not match false", + "schema": {"enum": [0]}, + "tests": [ + { + "description": "false is invalid", + "data": false, + "valid": false + }, + { + "description": "integer zero is valid", + "data": 0, + "valid": true + }, + { + "description": "float zero is valid", + "data": 0.0, + "valid": true + } + ] + }, + { + "description": "enum with 1 does not match true", + "schema": {"enum": [1]}, + "tests": [ + { + "description": "true is invalid", + "data": true, + "valid": false + }, + { + "description": "integer one is valid", + "data": 1, + "valid": true + }, + { + "description": "float one is valid", + "data": 1.0, + "valid": true + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/exclusiveMaximum.json python-jsonschema-4.6.0/json/tests/draft-next/exclusiveMaximum.json --- python-jsonschema-3.2.0/json/tests/draft-next/exclusiveMaximum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/exclusiveMaximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,30 @@ +[ + { + "description": "exclusiveMaximum validation", + "schema": { + "exclusiveMaximum": 3.0 + }, + "tests": [ + { + "description": "below the exclusiveMaximum is valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + }, + { + "description": "above the exclusiveMaximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/exclusiveMinimum.json python-jsonschema-4.6.0/json/tests/draft-next/exclusiveMinimum.json --- python-jsonschema-3.2.0/json/tests/draft-next/exclusiveMinimum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/exclusiveMinimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,30 @@ +[ + { + "description": "exclusiveMinimum validation", + "schema": { + "exclusiveMinimum": 1.1 + }, + "tests": [ + { + "description": "above the exclusiveMinimum is valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "below the exclusiveMinimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/format.json python-jsonschema-4.6.0/json/tests/draft-next/format.json --- python-jsonschema-3.2.0/json/tests/draft-next/format.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,686 @@ +[ + { + "description": "email format", + "schema": { "format": "email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "idn-email format", + "schema": { "format": "idn-email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "regex format", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "ipv4 format", + "schema": { "format": "ipv4" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "ipv6 format", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "idn-hostname format", + "schema": { "format": "idn-hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "hostname format", + "schema": { "format": "hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "date format", + "schema": { "format": "date" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "date-time format", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "time format", + "schema": { "format": "time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "json-pointer format", + "schema": { "format": "json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "relative-json-pointer format", + "schema": { "format": "relative-json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "iri format", + "schema": { "format": "iri" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "iri-reference format", + "schema": { "format": "iri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uri format", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uri-reference format", + "schema": { "format": "uri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uri-template format", + "schema": { "format": "uri-template" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uuid format", + "schema": { "format": "uuid" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "duration format", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/id.json python-jsonschema-4.6.0/json/tests/draft-next/id.json --- python-jsonschema-3.2.0/json/tests/draft-next/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,258 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": { + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/if-then-else.json python-jsonschema-4.6.0/json/tests/draft-next/if-then-else.json --- python-jsonschema-3.2.0/json/tests/draft-next/if-then-else.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/if-then-else.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,258 @@ +[ + { + "description": "ignore if without then or else", + "schema": { + "if": { + "const": 0 + } + }, + "tests": [ + { + "description": "valid when valid against lone if", + "data": 0, + "valid": true + }, + { + "description": "valid when invalid against lone if", + "data": "hello", + "valid": true + } + ] + }, + { + "description": "ignore then without if", + "schema": { + "then": { + "const": 0 + } + }, + "tests": [ + { + "description": "valid when valid against lone then", + "data": 0, + "valid": true + }, + { + "description": "valid when invalid against lone then", + "data": "hello", + "valid": true + } + ] + }, + { + "description": "ignore else without if", + "schema": { + "else": { + "const": 0 + } + }, + "tests": [ + { + "description": "valid when valid against lone else", + "data": 0, + "valid": true + }, + { + "description": "valid when invalid against lone else", + "data": "hello", + "valid": true + } + ] + }, + { + "description": "if and then without else", + "schema": { + "if": { + "exclusiveMaximum": 0 + }, + "then": { + "minimum": -10 + } + }, + "tests": [ + { + "description": "valid through then", + "data": -1, + "valid": true + }, + { + "description": "invalid through then", + "data": -100, + "valid": false + }, + { + "description": "valid when if test fails", + "data": 3, + "valid": true + } + ] + }, + { + "description": "if and else without then", + "schema": { + "if": { + "exclusiveMaximum": 0 + }, + "else": { + "multipleOf": 2 + } + }, + "tests": [ + { + "description": "valid when if test passes", + "data": -1, + "valid": true + }, + { + "description": "valid through else", + "data": 4, + "valid": true + }, + { + "description": "invalid through else", + "data": 3, + "valid": false + } + ] + }, + { + "description": "validate against correct branch, then vs else", + "schema": { + "if": { + "exclusiveMaximum": 0 + }, + "then": { + "minimum": -10 + }, + "else": { + "multipleOf": 2 + } + }, + "tests": [ + { + "description": "valid through then", + "data": -1, + "valid": true + }, + { + "description": "invalid through then", + "data": -100, + "valid": false + }, + { + "description": "valid through else", + "data": 4, + "valid": true + }, + { + "description": "invalid through else", + "data": 3, + "valid": false + } + ] + }, + { + "description": "non-interference across combined schemas", + "schema": { + "allOf": [ + { + "if": { + "exclusiveMaximum": 0 + } + }, + { + "then": { + "minimum": -10 + } + }, + { + "else": { + "multipleOf": 2 + } + } + ] + }, + "tests": [ + { + "description": "valid, but would have been invalid through then", + "data": -100, + "valid": true + }, + { + "description": "valid, but would have been invalid through else", + "data": 3, + "valid": true + } + ] + }, + { + "description": "if with boolean schema true", + "schema": { + "if": true, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema true in if always chooses the then path (valid)", + "data": "then", + "valid": true + }, + { + "description": "boolean schema true in if always chooses the then path (invalid)", + "data": "else", + "valid": false + } + ] + }, + { + "description": "if with boolean schema false", + "schema": { + "if": false, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema false in if always chooses the else path (invalid)", + "data": "then", + "valid": false + }, + { + "description": "boolean schema false in if always chooses the else path (valid)", + "data": "else", + "valid": true + } + ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/draft-next/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/draft-next/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "$defs": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/$defs/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/$defs/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/items.json python-jsonschema-4.6.0/json/tests/draft-next/items.json --- python-jsonschema-3.2.0/json/tests/draft-next/items.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/items.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,256 @@ +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + }, + { + "description": "JavaScript pseudo-array is valid", + "data": { + "0": "invalid", + "length": 1 + }, + "valid": true + } + ] + }, + { + "description": "items with boolean schema (true)", + "schema": {"items": true}, + "tests": [ + { + "description": "any array is valid", + "data": [ 1, "foo", true ], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "items with boolean schema (false)", + "schema": {"items": false}, + "tests": [ + { + "description": "any non-empty array is invalid", + "data": [ 1, "foo", true ], + "valid": false + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "items and subitems", + "schema": { + "$defs": { + "item": { + "type": "array", + "items": false, + "prefixItems": [ + { "$ref": "#/$defs/sub-item" }, + { "$ref": "#/$defs/sub-item" } + ] + }, + "sub-item": { + "type": "object", + "required": ["foo"] + } + }, + "type": "array", + "items": false, + "prefixItems": [ + { "$ref": "#/$defs/item" }, + { "$ref": "#/$defs/item" }, + { "$ref": "#/$defs/item" } + ] + }, + "tests": [ + { + "description": "valid items", + "data": [ + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": true + }, + { + "description": "too many items", + "data": [ + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "too many sub-items", + "data": [ + [ {"foo": null}, {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "wrong item", + "data": [ + {"foo": null}, + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "wrong sub-item", + "data": [ + [ {}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ], + [ {"foo": null}, {"foo": null} ] + ], + "valid": false + }, + { + "description": "fewer items is valid", + "data": [ + [ {"foo": null} ], + [ {"foo": null} ] + ], + "valid": true + } + ] + }, + { + "description": "nested items", + "schema": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + }, + "tests": [ + { + "description": "valid nested array", + "data": [[[[1]], [[2],[3]]], [[[4], [5], [6]]]], + "valid": true + }, + { + "description": "nested array with invalid type", + "data": [[[["1"]], [[2],[3]]], [[[4], [5], [6]]]], + "valid": false + }, + { + "description": "not deep enough", + "data": [[[1], [2],[3]], [[4], [5], [6]]], + "valid": false + } + ] + }, + { + "description": "prefixItems with no additional items allowed", + "schema": { + "prefixItems": [{}, {}, {}], + "items": false + }, + "tests": [ + { + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "equal number of items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "items should not look in applicators, valid case", + "schema": { + "allOf": [ + { "prefixItems": [ { "minimum": 3 } ] } + ], + "items": { "minimum": 5 } + }, + "tests": [ + { + "description": "prefixItems in allOf should not constrain items, invalid case", + "data": [ 3, 5 ], + "valid": false + }, + { + "description": "prefixItems in allOf should not constrain items, valid case", + "data": [ 5, 5 ], + "valid": true + } + ] + }, + { + "description": "prefixItems validation adjusts the starting index for items", + "schema": { + "prefixItems": [ { "type": "string" } ], + "items": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/maxContains.json python-jsonschema-4.6.0/json/tests/draft-next/maxContains.json --- python-jsonschema-3.2.0/json/tests/draft-next/maxContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/maxContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,129 @@ +[ + { + "description": "maxContains without contains is ignored", + "schema": { + "maxContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone maxContains", + "data": [1], + "valid": true + }, + { + "description": "two items still valid against lone maxContains", + "data": [1, 2], + "valid": true + }, + { + "description": "one property valid against lone maxContains", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "two properties still valid against lone maxContains", + "data": { "a": 1, "b": 2 }, + "valid": true + } + ] + }, + { + "description": "maxContains with contains", + "schema": { + "contains": { "const": 1 }, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty array", + "data": [], + "valid": false + }, + { + "description": "all elements match, valid maxContains", + "data": [1], + "valid": true + }, + { + "description": "all elements match, invalid maxContains", + "data": [1, 1], + "valid": false + }, + { + "description": "some elements match, valid maxContains", + "data": [1, 2], + "valid": true + }, + { + "description": "some elements match, invalid maxContains", + "data": [1, 2, 1], + "valid": false + }, + { + "description": "empty object", + "data": {}, + "valid": false + }, + { + "description": "all properties match, valid maxContains", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "all properties match, invalid maxContains", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "some properties match, valid maxContains", + "data": { "a": 1, "b": 2 }, + "valid": true + }, + { + "description": "some properties match, invalid maxContains", + "data": { "a": 1, "b": 2, "c": 1 }, + "valid": false + } + ] + }, + { + "description": "minContains < maxContains", + "schema": { + "contains": { "const": 1 }, + "minContains": 1, + "maxContains": 3 + }, + "tests": [ + { + "description": "array with actual < minContains < maxContains", + "data": [], + "valid": false + }, + { + "description": "array with minContains < actual < maxContains", + "data": [1, 1], + "valid": true + }, + { + "description": "array with minContains < maxContains < actual", + "data": [1, 1, 1, 1], + "valid": false + }, + { + "description": "object with actual < minContains < maxContains", + "data": {}, + "valid": false + }, + { + "description": "object with minContains < actual < maxContains", + "data": { "a": 1, "b": 1 }, + "valid": true + }, + { + "description": "object with minContains < maxContains < actual", + "data": { "a": 1, "b": 1, "c": 1, "d": 1 }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/maximum.json python-jsonschema-4.6.0/json/tests/draft-next/maximum.json --- python-jsonschema-3.2.0/json/tests/draft-next/maximum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,54 @@ +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "boundary point is valid", + "data": 3.0, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/maxItems.json python-jsonschema-4.6.0/json/tests/draft-next/maxItems.json --- python-jsonschema-3.2.0/json/tests/draft-next/maxItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/maxItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,28 @@ +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/maxLength.json python-jsonschema-4.6.0/json/tests/draft-next/maxLength.json --- python-jsonschema-3.2.0/json/tests/draft-next/maxLength.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/maxLength.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,33 @@ +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + }, + { + "description": "two supplementary Unicode code points is long enough", + "data": "\uD83D\uDCA9\uD83D\uDCA9", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/maxProperties.json python-jsonschema-4.6.0/json/tests/draft-next/maxProperties.json --- python-jsonschema-3.2.0/json/tests/draft-next/maxProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,54 @@ +[ + { + "description": "maxProperties validation", + "schema": {"maxProperties": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "too long is invalid", + "data": {"foo": 1, "bar": 2, "baz": 3}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/minContains.json python-jsonschema-4.6.0/json/tests/draft-next/minContains.json --- python-jsonschema-3.2.0/json/tests/draft-next/minContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/minContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,197 @@ +[ + { + "description": "minContains without contains is ignored", + "schema": { + "minContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone minContains", + "data": [1], + "valid": true + }, + { + "description": "zero items still valid against lone minContains", + "data": [], + "valid": true + } + ] + }, + { + "description": "minContains=1 with contains", + "schema": { + "contains": { "const": 1 }, + "minContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [], + "valid": false + }, + { + "description": "no elements match", + "data": [2], + "valid": false + }, + { + "description": "single element matches, valid minContains", + "data": [1], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [1, 2], + "valid": true + }, + { + "description": "all elements match, valid minContains", + "data": [1, 1], + "valid": true + } + ] + }, + { + "description": "minContains=2 with contains", + "schema": { + "contains": { "const": 1 }, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [1], + "valid": false + }, + { + "description": "some elements match, invalid minContains", + "data": [1, 2], + "valid": false + }, + { + "description": "all elements match, valid minContains (exactly as needed)", + "data": [1, 1], + "valid": true + }, + { + "description": "all elements match, valid minContains (more than needed)", + "data": [1, 1, 1], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [1, 2, 1], + "valid": true + } + ] + }, + { + "description": "maxContains = minContains", + "schema": { + "contains": { "const": 1 }, + "maxContains": 2, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [1], + "valid": false + }, + { + "description": "all elements match, invalid maxContains", + "data": [1, 1, 1], + "valid": false + }, + { + "description": "all elements match, valid maxContains and minContains", + "data": [1, 1], + "valid": true + } + ] + }, + { + "description": "maxContains < minContains", + "schema": { + "contains": { "const": 1 }, + "maxContains": 1, + "minContains": 3 + }, + "tests": [ + { + "description": "empty data", + "data": [], + "valid": false + }, + { + "description": "invalid minContains", + "data": [1], + "valid": false + }, + { + "description": "invalid maxContains", + "data": [1, 1, 1], + "valid": false + }, + { + "description": "invalid maxContains and minContains", + "data": [1, 1], + "valid": false + } + ] + }, + { + "description": "minContains = 0", + "schema": { + "contains": { "const": 1 }, + "minContains": 0 + }, + "tests": [ + { + "description": "empty data", + "data": [], + "valid": true + }, + { + "description": "minContains = 0 makes contains always pass", + "data": [2], + "valid": true + } + ] + }, + { + "description": "minContains = 0 with maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 0, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "not more than maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "too many", + "data": [ 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/minimum.json python-jsonschema-4.6.0/json/tests/draft-next/minimum.json --- python-jsonschema-3.2.0/json/tests/draft-next/minimum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,69 @@ +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "boundary point is valid", + "data": 1.1, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "minimum validation with signed integer", + "schema": {"minimum": -2}, + "tests": [ + { + "description": "negative above the minimum is valid", + "data": -1, + "valid": true + }, + { + "description": "positive above the minimum is valid", + "data": 0, + "valid": true + }, + { + "description": "boundary point is valid", + "data": -2, + "valid": true + }, + { + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", + "data": -3, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/minItems.json python-jsonschema-4.6.0/json/tests/draft-next/minItems.json --- python-jsonschema-3.2.0/json/tests/draft-next/minItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/minItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,28 @@ +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/minLength.json python-jsonschema-4.6.0/json/tests/draft-next/minLength.json --- python-jsonschema-3.2.0/json/tests/draft-next/minLength.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/minLength.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,33 @@ +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + }, + { + "description": "one supplementary Unicode code point is not long enough", + "data": "\uD83D\uDCA9", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/minProperties.json python-jsonschema-4.6.0/json/tests/draft-next/minProperties.json --- python-jsonschema-3.2.0/json/tests/draft-next/minProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/minProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "minProperties validation", + "schema": {"minProperties": 1}, + "tests": [ + { + "description": "longer is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "too short is invalid", + "data": {}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/multipleOf.json python-jsonschema-4.6.0/json/tests/draft-next/multipleOf.json --- python-jsonschema-3.2.0/json/tests/draft-next/multipleOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,71 @@ +[ + { + "description": "by int", + "schema": {"multipleOf": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"multipleOf": 1.5}, + "tests": [ + { + "description": "zero is multiple of anything", + "data": 0, + "valid": true + }, + { + "description": "4.5 is multiple of 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not multiple of 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"multipleOf": 0.0001}, + "tests": [ + { + "description": "0.0075 is multiple of 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not multiple of 0.0001", + "data": 0.00751, + "valid": false + } + ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/not.json python-jsonschema-4.6.0/json/tests/draft-next/not.json --- python-jsonschema-3.2.0/json/tests/draft-next/not.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/not.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,117 @@ +[ + { + "description": "not", + "schema": { + "not": {"type": "integer"} + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "not multiple types", + "schema": { + "not": {"type": ["integer", "boolean"]} + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "not more complex schema", + "schema": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + } + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "forbidden property", + "schema": { + "properties": { + "foo": { + "not": {} + } + } + }, + "tests": [ + { + "description": "property present", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "property absent", + "data": {"bar": 1, "baz": 2}, + "valid": true + } + ] + }, + { + "description": "not with boolean schema true", + "schema": {"not": true}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "not with boolean schema false", + "schema": {"not": false}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/oneOf.json python-jsonschema-4.6.0/json/tests/draft-next/oneOf.json --- python-jsonschema-3.2.0/json/tests/draft-next/oneOf.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,274 @@ +[ + { + "description": "oneOf", + "schema": { + "oneOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": 1, + "valid": true + }, + { + "description": "second oneOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both oneOf valid", + "data": 3, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "oneOf with base schema", + "schema": { + "type": "string", + "oneOf" : [ + { + "minLength": 2 + }, + { + "maxLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one oneOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both oneOf valid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf with boolean schemas, all true", + "schema": {"oneOf": [true, true, true]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf with boolean schemas, one true", + "schema": {"oneOf": [true, false, false]}, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "oneOf with boolean schemas, more than one true", + "schema": {"oneOf": [true, true, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf with boolean schemas, all false", + "schema": {"oneOf": [false, false, false]}, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "oneOf complex types", + "schema": { + "oneOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid (complex)", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "second oneOf valid (complex)", + "data": {"foo": "baz"}, + "valid": true + }, + { + "description": "both oneOf valid (complex)", + "data": {"foo": "baz", "bar": 2}, + "valid": false + }, + { + "description": "neither oneOf valid (complex)", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "oneOf with empty schema", + "schema": { + "oneOf": [ + { "type": "number" }, + {} + ] + }, + "tests": [ + { + "description": "one valid - valid", + "data": "foo", + "valid": true + }, + { + "description": "both valid - invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "oneOf with required", + "schema": { + "type": "object", + "oneOf": [ + { "required": ["foo", "bar"] }, + { "required": ["foo", "baz"] } + ] + }, + "tests": [ + { + "description": "both invalid - invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "first valid - valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "second valid - valid", + "data": {"foo": 1, "baz": 3}, + "valid": true + }, + { + "description": "both valid - invalid", + "data": {"foo": 1, "bar": 2, "baz" : 3}, + "valid": false + } + ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": true, + "baz": true + }, + "required": ["bar"] + }, + { + "properties": { + "foo": true + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/bignum.json python-jsonschema-4.6.0/json/tests/draft-next/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/bignum.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,93 @@ +[ + { + "description": "integer", + "schema": { "type": "integer" }, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + }, + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": { "type": "number" }, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": { "type": "string" }, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": { "maximum": 18446744073709551615 }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "exclusiveMaximum": 972783798187987123879878123.18878137 + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": { "minimum": -18446744073709551615 }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "exclusiveMinimum": -972783798187987123879878123.18878137 + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/draft-next/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/ecmascript-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,552 @@ +[ + { + "description": "ECMA 262 regex $ does not match trailing newline", + "schema": { + "type": "string", + "pattern": "^abc$" + }, + "tests": [ + { + "description": "matches in Python, but should not in jsonschema", + "data": "abc\\n", + "valid": false + }, + { + "description": "should match", + "data": "abc", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex converts \\t to horizontal tab", + "schema": { + "type": "string", + "pattern": "^\\t$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\t", + "valid": false + }, + { + "description": "matches", + "data": "\u0009", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and upper letter", + "schema": { + "type": "string", + "pattern": "^\\cC$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cC", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 regex escapes control codes with \\c and lower letter", + "schema": { + "type": "string", + "pattern": "^\\cc$" + }, + "tests": [ + { + "description": "does not match", + "data": "\\cc", + "valid": false + }, + { + "description": "matches", + "data": "\u0003", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\d matches ascii digits only", + "schema": { + "type": "string", + "pattern": "^\\d$" + }, + "tests": [ + { + "description": "ASCII zero matches", + "data": "0", + "valid": true + }, + { + "description": "NKO DIGIT ZERO does not match (unlike e.g. Python)", + "data": "߀", + "valid": false + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) does not match", + "data": "\u07c0", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\D matches everything but ascii digits", + "schema": { + "type": "string", + "pattern": "^\\D$" + }, + "tests": [ + { + "description": "ASCII zero does not match", + "data": "0", + "valid": false + }, + { + "description": "NKO DIGIT ZERO matches (unlike e.g. Python)", + "data": "߀", + "valid": true + }, + { + "description": "NKO DIGIT ZERO (as \\u escape) matches", + "data": "\u07c0", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\w matches ascii letters only", + "schema": { + "type": "string", + "pattern": "^\\w$" + }, + "tests": [ + { + "description": "ASCII 'a' matches", + "data": "a", + "valid": true + }, + { + "description": "latin-1 e-acute does not match (unlike e.g. Python)", + "data": "é", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\W matches everything but ascii letters", + "schema": { + "type": "string", + "pattern": "^\\W$" + }, + "tests": [ + { + "description": "ASCII 'a' does not match", + "data": "a", + "valid": false + }, + { + "description": "latin-1 e-acute matches (unlike e.g. Python)", + "data": "é", + "valid": true + } + ] + }, + { + "description": "ECMA 262 \\s matches whitespace", + "schema": { + "type": "string", + "pattern": "^\\s$" + }, + "tests": [ + { + "description": "ASCII space matches", + "data": " ", + "valid": true + }, + { + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", + "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", + "valid": false + } + ] + }, + { + "description": "ECMA 262 \\S matches everything but whitespace", + "schema": { + "type": "string", + "pattern": "^\\S$" + }, + "tests": [ + { + "description": "ASCII space does not match", + "data": " ", + "valid": false + }, + { + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", + "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/draft-next/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/date.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/date.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/date.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/date.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,223 @@ +[ + { + "description": "validation of date strings", + "schema": { "format": "date" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid date string", + "data": "1963-06-19", + "valid": true + }, + { + "description": "a valid date string with 31 days in January", + "data": "2020-01-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in January", + "data": "2020-01-32", + "valid": false + }, + { + "description": "a valid date string with 28 days in February (normal)", + "data": "2021-02-28", + "valid": true + }, + { + "description": "a invalid date string with 29 days in February (normal)", + "data": "2021-02-29", + "valid": false + }, + { + "description": "a valid date string with 29 days in February (leap)", + "data": "2020-02-29", + "valid": true + }, + { + "description": "a invalid date string with 30 days in February (leap)", + "data": "2020-02-30", + "valid": false + }, + { + "description": "a valid date string with 31 days in March", + "data": "2020-03-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in March", + "data": "2020-03-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in April", + "data": "2020-04-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in April", + "data": "2020-04-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in May", + "data": "2020-05-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in May", + "data": "2020-05-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in June", + "data": "2020-06-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in June", + "data": "2020-06-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in July", + "data": "2020-07-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in July", + "data": "2020-07-32", + "valid": false + }, + { + "description": "a valid date string with 31 days in August", + "data": "2020-08-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in August", + "data": "2020-08-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in September", + "data": "2020-09-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in September", + "data": "2020-09-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in October", + "data": "2020-10-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in October", + "data": "2020-10-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in November", + "data": "2020-11-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in November", + "data": "2020-11-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in December", + "data": "2020-12-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in December", + "data": "2020-12-32", + "valid": false + }, + { + "description": "a invalid date string with invalid month", + "data": "2020-13-01", + "valid": false + }, + { + "description": "an invalid date string", + "data": "06/19/1963", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350", + "valid": false + }, + { + "description": "non-padded month dates are not valid", + "data": "1998-1-20", + "valid": false + }, + { + "description": "non-padded day dates are not valid", + "data": "1998-01-1", + "valid": false + }, + { + "description": "invalid month", + "data": "1998-13-01", + "valid": false + }, + { + "description": "invalid month-day combination", + "data": "1998-04-31", + "valid": false + }, + { + "description": "2021 is not a leap year", + "data": "2021-02-29", + "valid": false + }, + { + "description": "2020 is a leap year", + "data": "2020-02-29", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1963-06-1৪", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/date-time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,133 @@ +[ + { + "description": "validation of date-time strings", + "schema": { "format": "date-time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "a valid date-time string without second fraction", + "data": "1963-06-19T08:30:06Z", + "valid": true + }, + { + "description": "a valid date-time string with plus offset", + "data": "1937-01-01T12:00:27.87+00:20", + "valid": true + }, + { + "description": "a valid date-time string with minus offset", + "data": "1990-12-31T15:59:50.123-08:00", + "valid": true + }, + { + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", + "valid": false + }, + { + "description": "an invalid offset in date-time string", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", + "valid": false + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "case-insensitive T and Z", + "data": "1963-06-19t08:30:06.283185z", + "valid": true + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/duration.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/duration.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/duration.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/duration.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,128 @@ +[ + { + "description": "validation of duration strings", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid duration string", + "data": "P4DT12H30M5S", + "valid": true + }, + { + "description": "an invalid duration string", + "data": "PT1D", + "valid": false + }, + { + "description": "no elements present", + "data": "P", + "valid": false + }, + { + "description": "no time elements present", + "data": "P1YT", + "valid": false + }, + { + "description": "no date or time elements present", + "data": "PT", + "valid": false + }, + { + "description": "elements out of order", + "data": "P2D1Y", + "valid": false + }, + { + "description": "missing time separator", + "data": "P1D2H", + "valid": false + }, + { + "description": "time element in the date position", + "data": "P2S", + "valid": false + }, + { + "description": "four years duration", + "data": "P4Y", + "valid": true + }, + { + "description": "zero time, in seconds", + "data": "PT0S", + "valid": true + }, + { + "description": "zero time, in days", + "data": "P0D", + "valid": true + }, + { + "description": "one month duration", + "data": "P1M", + "valid": true + }, + { + "description": "one minute duration", + "data": "PT1M", + "valid": true + }, + { + "description": "one and a half days, in hours", + "data": "PT36H", + "valid": true + }, + { + "description": "one and a half days, in days and hours", + "data": "P1DT12H", + "valid": true + }, + { + "description": "two weeks", + "data": "P2W", + "valid": true + }, + { + "description": "weeks cannot be combined with other units", + "data": "P1Y2W", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "P২Y", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/email.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,118 @@ +[ + { + "description": "validation of e-mail addresses", + "schema": { "format": "email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "a quoted string with a space in the local part is valid", + "data": "\"joe bloggs\"@example.com", + "valid": true + }, + { + "description": "a quoted string with a double dot in the local part is valid", + "data": "\"joe..bloggs\"@example.com", + "valid": true + }, + { + "description": "a quoted string with a @ in the local part is valid", + "data": "\"joe@bloggs\"@example.com", + "valid": true + }, + { + "description": "an IPv4-address-literal after the @ is valid", + "data": "joe.bloggs@[127.0.0.1]", + "valid": true + }, + { + "description": "an IPv6-address-literal after the @ is valid", + "data": "joe.bloggs@[IPv6:::1]", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false + }, + { + "description": "an invalid domain", + "data": "joe.bloggs@invalid=domain.com", + "valid": false + }, + { + "description": "an invalid IPv4-address-literal", + "data": "joe.bloggs@[127.0.0.300]", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/hostname.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,98 @@ +[ + { + "description": "validation of host names", + "schema": { "format": "hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a valid punycoded IDN hostname", + "data": "xn--4gbwdl.xn--wgbh1c", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/idn-email.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/idn-email.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/idn-email.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/idn-email.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,58 @@ +[ + { + "description": "validation of an internationalized e-mail addresses", + "schema": { "format": "idn-email" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid idn e-mail (example@example.test in Hangul)", + "data": "실례@실례.테스트", + "valid": true + }, + { + "description": "an invalid idn e-mail address", + "data": "2962", + "valid": false + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/idn-hostname.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/idn-hostname.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/idn-hostname.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/idn-hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,304 @@ +[ + { + "description": "validation of internationalized host names", + "schema": { "format": "idn-hostname" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid host name (example.test in Hangul)", + "data": "실례.테스트", + "valid": true + }, + { + "description": "illegal first char U+302E Hangul single dot tone mark", + "data": "〮실례.테스트", + "valid": false + }, + { + "description": "contains illegal char U+302E Hangul single dot tone mark", + "data": "실〮례.테스트", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", + "valid": false + }, + { + "description": "invalid label, correct Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", + "data": "-> $1.00 <--", + "valid": false + }, + { + "description": "valid Chinese Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", + "data": "xn--ihqwcrb4cv8a8dqg056pqjye", + "valid": true + }, + { + "description": "invalid Punycode", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "xn--X", + "valid": false + }, + { + "description": "U-label contains \"--\" in the 3rd and 4th position", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "XN--aa---o47jg78q", + "valid": false + }, + { + "description": "U-label starts with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello", + "valid": false + }, + { + "description": "U-label ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "hello-", + "valid": false + }, + { + "description": "U-label starts and ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello-", + "valid": false + }, + { + "description": "Begins with a Spacing Combining Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0903hello", + "valid": false + }, + { + "description": "Begins with a Nonspacing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0300hello", + "valid": false + }, + { + "description": "Begins with an Enclosing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0488hello", + "valid": false + }, + { + "description": "Exceptions that are PVALID, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u00df\u03c2\u0f0b\u3007", + "valid": true + }, + { + "description": "Exceptions that are PVALID, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u06fd\u06fe", + "valid": true + }, + { + "description": "Exceptions that are DISALLOWED, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u0640\u07fa", + "valid": false + }, + { + "description": "Exceptions that are DISALLOWED, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", + "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", + "valid": false + }, + { + "description": "MIDDLE DOT with no preceding 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "a\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing preceding", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with no following 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7a", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing following", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7", + "valid": false + }, + { + "description": "MIDDLE DOT with surrounding 'l's", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7l", + "valid": true + }, + { + "description": "Greek KERAIA not followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375S", + "valid": false + }, + { + "description": "Greek KERAIA not followed by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375", + "valid": false + }, + { + "description": "Greek KERAIA followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375\u03b2", + "valid": true + }, + { + "description": "Hebrew GERESH not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "A\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05d0\u05f3\u05d1", + "valid": true + }, + { + "description": "Hebrew GERSHAYIM not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "A\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05d0\u05f4\u05d1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "def\u30fbabc", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with no other characters", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with Hiragana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u3041", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Katakana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u30a1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u4e08", + "valid": true + }, + { + "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0660\u06f0", + "valid": false + }, + { + "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0628\u0660\u0628", + "valid": true + }, + { + "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", + "data": "\u06f00", + "valid": true + }, + { + "description": "ZERO WIDTH JOINER not preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u094d\u200d\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", + "data": "\u0915\u094d\u200c\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", + "data": "\u0628\u064a\u200c\u0628\u064a", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/ipv4.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,84 @@ +[ + { + "description": "validation of IP addresses", + "schema": { "format": "ipv4" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/ipv6.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,208 @@ +[ + { + "description": "validation of IPv6 addresses", + "schema": { "format": "ipv6" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/iri.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/iri.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/iri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/iri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,83 @@ +[ + { + "description": "validation of IRIs", + "schema": { "format": "iri" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IRI with anchor tag", + "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", + "valid": true + }, + { + "description": "a valid IRI with anchor tag and parentheses", + "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", + "valid": true + }, + { + "description": "a valid IRI with URL-encoded stuff", + "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", + "valid": true + }, + { + "description": "a valid IRI with many special characters", + "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", + "valid": true + }, + { + "description": "a valid IRI based on IPv6", + "data": "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", + "valid": true + }, + { + "description": "an invalid IRI based on IPv6", + "data": "http://2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "valid": false + }, + { + "description": "an invalid relative IRI Reference", + "data": "/abc", + "valid": false + }, + { + "description": "an invalid IRI", + "data": "\\\\WINDOWS\\filëßåré", + "valid": false + }, + { + "description": "an invalid IRI though valid IRI reference", + "data": "âππ", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/iri-reference.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/iri-reference.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/iri-reference.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/iri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,73 @@ +[ + { + "description": "validation of IRI References", + "schema": { "format": "iri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid IRI", + "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", + "valid": true + }, + { + "description": "a valid protocol-relative IRI Reference", + "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", + "valid": true + }, + { + "description": "a valid relative IRI Reference", + "data": "/âππ", + "valid": true + }, + { + "description": "an invalid IRI Reference", + "data": "\\\\WINDOWS\\filëßåré", + "valid": false + }, + { + "description": "a valid IRI Reference", + "data": "âππ", + "valid": true + }, + { + "description": "a valid IRI fragment", + "data": "#ƒrägmênt", + "valid": true + }, + { + "description": "an invalid IRI fragment", + "data": "#ƒräg\\mênt", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/json-pointer.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/json-pointer.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,198 @@ +[ + { + "description": "validation of JSON-pointers (JSON String Representation)", + "schema": { "format": "json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid JSON-pointer", + "data": "/foo/bar~0/baz~1/%a", + "valid": true + }, + { + "description": "not a valid JSON-pointer (~ not escaped)", + "data": "/foo/bar~", + "valid": false + }, + { + "description": "valid JSON-pointer with empty segment", + "data": "/foo//bar", + "valid": true + }, + { + "description": "valid JSON-pointer with the last empty segment", + "data": "/foo/bar/", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #1", + "data": "", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #2", + "data": "/foo", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #3", + "data": "/foo/0", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #4", + "data": "/", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #5", + "data": "/a~1b", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #6", + "data": "/c%d", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #7", + "data": "/e^f", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #8", + "data": "/g|h", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #9", + "data": "/i\\j", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #10", + "data": "/k\"l", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #11", + "data": "/ ", + "valid": true + }, + { + "description": "valid JSON-pointer as stated in RFC 6901 #12", + "data": "/m~0n", + "valid": true + }, + { + "description": "valid JSON-pointer used adding to the last array position", + "data": "/foo/-", + "valid": true + }, + { + "description": "valid JSON-pointer (- used as object member name)", + "data": "/foo/-/bar", + "valid": true + }, + { + "description": "valid JSON-pointer (multiple escaped characters)", + "data": "/~1~0~0~1~1", + "valid": true + }, + { + "description": "valid JSON-pointer (escaped with fraction part) #1", + "data": "/~1.1", + "valid": true + }, + { + "description": "valid JSON-pointer (escaped with fraction part) #2", + "data": "/~0.1", + "valid": true + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #1", + "data": "#", + "valid": false + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #2", + "data": "#/", + "valid": false + }, + { + "description": "not a valid JSON-pointer (URI Fragment Identifier) #3", + "data": "#a", + "valid": false + }, + { + "description": "not a valid JSON-pointer (some escaped, but not all) #1", + "data": "/~0~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (some escaped, but not all) #2", + "data": "/~0/~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (wrong escape character) #1", + "data": "/~2", + "valid": false + }, + { + "description": "not a valid JSON-pointer (wrong escape character) #2", + "data": "/~-1", + "valid": false + }, + { + "description": "not a valid JSON-pointer (multiple characters not escaped)", + "data": "/~~", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #1", + "data": "a", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #2", + "data": "0", + "valid": false + }, + { + "description": "not a valid JSON-pointer (isn't empty nor starts with /) #3", + "data": "a/a", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/regex.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/regex.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,48 @@ +[ + { + "description": "validation of regular expressions", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid regular expression", + "data": "([abc])+\\s+$", + "valid": true + }, + { + "description": "a regular expression with unclosed parens is invalid", + "data": "^(abc]", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/relative-json-pointer.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/relative-json-pointer.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/relative-json-pointer.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/relative-json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,83 @@ +[ + { + "description": "validation of Relative JSON Pointers (RJP)", + "schema": { "format": "relative-json-pointer" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid upwards RJP", + "data": "1", + "valid": true + }, + { + "description": "a valid downwards RJP", + "data": "0/foo/bar", + "valid": true + }, + { + "description": "a valid up and then down RJP, with array index", + "data": "2/0/baz/1/zip", + "valid": true + }, + { + "description": "a valid RJP taking the member or index name", + "data": "0#", + "valid": true + }, + { + "description": "an invalid RJP that is a valid JSON Pointer", + "data": "/foo/bar", + "valid": false + }, + { + "description": "negative prefix", + "data": "-1/foo/bar", + "valid": false + }, + { + "description": "## is not a valid json-pointer", + "data": "0##", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus json-pointer", + "data": "01/a", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus octothorpe", + "data": "01#", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/time.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/time.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/time.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/time.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,198 @@ +[ + { + "description": "validation of time strings", + "schema": { "format": "time" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid time string", + "data": "08:30:06Z", + "valid": true + }, + { + "description": "a valid time string with leap second, Zulu", + "data": "23:59:60Z", + "valid": true + }, + { + "description": "invalid leap second, Zulu (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "invalid leap second, Zulu (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "valid leap second, zero time-offset", + "data": "23:59:60+00:00", + "valid": true + }, + { + "description": "invalid leap second, zero time-offset (wrong hour)", + "data": "22:59:60+00:00", + "valid": false + }, + { + "description": "invalid leap second, zero time-offset (wrong minute)", + "data": "23:58:60+00:00", + "valid": false + }, + { + "description": "valid leap second, positive time-offset", + "data": "01:29:60+01:30", + "valid": true + }, + { + "description": "valid leap second, large positive time-offset", + "data": "23:29:60+23:30", + "valid": true + }, + { + "description": "invalid leap second, positive time-offset (wrong hour)", + "data": "23:59:60+01:00", + "valid": false + }, + { + "description": "invalid leap second, positive time-offset (wrong minute)", + "data": "23:59:60+00:30", + "valid": false + }, + { + "description": "valid leap second, negative time-offset", + "data": "15:59:60-08:00", + "valid": true + }, + { + "description": "valid leap second, large negative time-offset", + "data": "00:29:60-23:30", + "valid": true + }, + { + "description": "invalid leap second, negative time-offset (wrong hour)", + "data": "23:59:60-01:00", + "valid": false + }, + { + "description": "invalid leap second, negative time-offset (wrong minute)", + "data": "23:59:60-00:30", + "valid": false + }, + { + "description": "a valid time string with second fraction", + "data": "23:20:50.52Z", + "valid": true + }, + { + "description": "a valid time string with precise second fraction", + "data": "08:30:06.283185Z", + "valid": true + }, + { + "description": "a valid time string with plus offset", + "data": "08:30:06+00:20", + "valid": true + }, + { + "description": "a valid time string with minus offset", + "data": "08:30:06-08:00", + "valid": true + }, + { + "description": "a valid time string with case-insensitive Z", + "data": "08:30:06z", + "valid": true + }, + { + "description": "an invalid time string with invalid hour", + "data": "24:00:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid minute", + "data": "00:60:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid second", + "data": "00:00:61Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset hour", + "data": "01:02:03+24:00", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset minute", + "data": "01:02:03+00:60", + "valid": false + }, + { + "description": "an invalid time string with invalid time with both Z and numoffset", + "data": "01:02:03Z+00:30", + "valid": false + }, + { + "description": "an invalid offset indicator", + "data": "08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "01:01:01,1111", + "valid": false + }, + { + "description": "no time offset", + "data": "12:00:00", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২:00:00Z", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uri.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uri.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,108 @@ +[ + { + "description": "validation of URIs", + "schema": { "format": "uri" }, + "tests": [ + { + "description": "a valid URL with anchor tag", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid URL with anchor tag and parentheses", + "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", + "valid": true + }, + { + "description": "a valid URL with URL-encoded stuff", + "data": "http://foo.bar/?q=Test%20URL-encoded%20stuff", + "valid": true + }, + { + "description": "a valid puny-coded URL ", + "data": "http://xn--nw2a.xn--j6w193g/", + "valid": true + }, + { + "description": "a valid URL with many special characters", + "data": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", + "valid": true + }, + { + "description": "a valid URL based on IPv4", + "data": "http://223.255.255.254", + "valid": true + }, + { + "description": "a valid URL with ftp scheme", + "data": "ftp://ftp.is.co.za/rfc/rfc1808.txt", + "valid": true + }, + { + "description": "a valid URL for a simple text file", + "data": "http://www.ietf.org/rfc/rfc2396.txt", + "valid": true + }, + { + "description": "a valid URL ", + "data": "ldap://[2001:db8::7]/c=GB?objectClass?one", + "valid": true + }, + { + "description": "a valid mailto URI", + "data": "mailto:John.Doe@example.com", + "valid": true + }, + { + "description": "a valid newsgroup URI", + "data": "news:comp.infosystems.www.servers.unix", + "valid": true + }, + { + "description": "a valid tel URI", + "data": "tel:+1-816-555-1212", + "valid": true + }, + { + "description": "a valid URN", + "data": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", + "valid": true + }, + { + "description": "an invalid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": false + }, + { + "description": "an invalid relative URI Reference", + "data": "/abc", + "valid": false + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + }, + { + "description": "an invalid URI with spaces", + "data": "http:// shouldfail.com", + "valid": false + }, + { + "description": "an invalid URI with spaces and missing scheme", + "data": ":// should fail", + "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uri-reference.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uri-reference.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uri-reference.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,73 @@ +[ + { + "description": "validation of URI References", + "schema": { "format": "uri-reference" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI Reference", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid relative URI Reference", + "data": "/abc", + "valid": true + }, + { + "description": "an invalid URI Reference", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "a valid URI Reference", + "data": "abc", + "valid": true + }, + { + "description": "a valid URI fragment", + "data": "#fragment", + "valid": true + }, + { + "description": "an invalid URI fragment", + "data": "#frag\\ment", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uri-template.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uri-template.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uri-template.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uri-template.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,58 @@ +[ + { + "description": "format: uri-template", + "schema": { "format": "uri-template" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid uri-template", + "data": "http://example.com/dictionary/{term:1}/{term}", + "valid": true + }, + { + "description": "an invalid uri-template", + "data": "http://example.com/dictionary/{term:1}/{term", + "valid": false + }, + { + "description": "a valid uri-template without variables", + "data": "http://example.com/dictionary", + "valid": true + }, + { + "description": "a valid relative uri-template", + "data": "dictionary/{term:1}/{term}", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uuid.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uuid.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format/uuid.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format/uuid.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,85 @@ +[ + { + "description": "uuid format", + "schema": { + "format": "uuid" + }, + "tests": [ + { + "description": "all upper-case", + "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", + "valid": true + }, + { + "description": "all lower-case", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", + "valid": true + }, + { + "description": "mixed case", + "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", + "valid": true + }, + { + "description": "all zeroes is valid", + "data": "00000000-0000-0000-0000-000000000000", + "valid": true + }, + { + "description": "wrong length", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": false + }, + { + "description": "missing section", + "data": "2eb8aa08-aa98-11ea-73b441d16380", + "valid": false + }, + { + "description": "bad characters (not hex)", + "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", + "valid": false + }, + { + "description": "no dashes", + "data": "2eb8aa08aa9811eab4aa73b441d16380", + "valid": false + }, + { + "description": "too few dashes", + "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", + "valid": false + }, + { + "description": "too many dashes", + "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", + "valid": false + }, + { + "description": "dashes in the wrong spot", + "data": "2eb8aa08aa9811eab4aa73b441d16380----", + "valid": false + }, + { + "description": "valid version 4", + "data": "98d80576-482e-427f-8434-7f86890ab222", + "valid": true + }, + { + "description": "valid version 5", + "data": "99c17cbb-656f-564a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 6", + "data": "99c17cbb-656f-664a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 15", + "data": "99c17cbb-656f-f64a-940f-1a4568f03487", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/format-assertion.json python-jsonschema-4.6.0/json/tests/draft-next/optional/format-assertion.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/format-assertion.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/format-assertion.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,42 @@ +[ + { + "description": "schema that uses custom metaschema with format-assertion: false", + "schema": { + "$id": "https://schema/using/format-assertion/false", + "$schema": "http://localhost:1234/draft-next/format-assertion-false.json", + "format": "ipv4" + }, + "tests": [ + { + "description": "format-assertion: false: valid string", + "data": "127.0.0.1", + "valid": true + }, + { + "description": "format-assertion: false: invalid string", + "data": "not-an-ipv4", + "valid": false + } + ] + }, + { + "description": "schema that uses custom metaschema with format-assertion: true", + "schema": { + "$id": "https://schema/using/format-assertion/true", + "$schema": "http://localhost:1234/draft-next/format-assertion-true.json", + "format": "ipv4" + }, + "tests": [ + { + "description": "format-assertion: true: valid string", + "data": "127.0.0.1", + "valid": true + }, + { + "description": "format-assertion: true: invalid string", + "data": "not-an-ipv4", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/draft-next/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/optional/refOfUnknownKeyword.json python-jsonschema-4.6.0/json/tests/draft-next/optional/refOfUnknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft-next/optional/refOfUnknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/optional/refOfUnknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,44 @@ +[ + { + "description": "reference of a root arbitrary keyword ", + "schema": { + "unknown-keyword": {"type": "integer"}, + "properties": { + "bar": {"$ref": "#/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "reference of an arbitrary keyword of a sub-schema", + "schema": { + "properties": { + "foo": {"unknown-keyword": {"type": "integer"}}, + "bar": {"$ref": "#/properties/foo/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/pattern.json python-jsonschema-4.6.0/json/tests/draft-next/pattern.json --- python-jsonschema-3.2.0/json/tests/draft-next/pattern.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,59 @@ +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + }, + { + "description": "pattern is not anchored", + "schema": {"pattern": "a+"}, + "tests": [ + { + "description": "matches a substring", + "data": "xxaayy", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/patternProperties.json python-jsonschema-4.6.0/json/tests/draft-next/patternProperties.json --- python-jsonschema-3.2.0/json/tests/draft-next/patternProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/patternProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,156 @@ +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["foo"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + }, + { + "description": "patternProperties with boolean schemas", + "schema": { + "patternProperties": { + "f.*": true, + "b.*": false + } + }, + "tests": [ + { + "description": "object with property matching schema true is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property matching schema false is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "object with both properties is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "object with a property matching both true and false is invalid", + "data": {"foobar":1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/prefixItems.json python-jsonschema-4.6.0/json/tests/draft-next/prefixItems.json --- python-jsonschema-3.2.0/json/tests/draft-next/prefixItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/prefixItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,81 @@ +[ + { + "description": "a schema given for prefixItems", + "schema": { + "prefixItems": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + }, + { + "description": "incomplete array of items", + "data": [ 1 ], + "valid": true + }, + { + "description": "array with additional items", + "data": [ 1, "foo", true ], + "valid": true + }, + { + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "JavaScript pseudo-array is valid", + "data": { + "0": "invalid", + "1": "valid", + "length": 2 + }, + "valid": true + } + ] + }, + { + "description": "prefixItems with boolean schemas", + "schema": { + "prefixItems": [true, false] + }, + "tests": [ + { + "description": "array with one item is valid", + "data": [ 1 ], + "valid": true + }, + { + "description": "array with two items is invalid", + "data": [ 1, "foo" ], + "valid": false + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "additional items are allowed by default", + "schema": {"prefixItems": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/properties.json python-jsonschema-4.6.0/json/tests/draft-next/properties.json --- python-jsonschema-3.2.0/json/tests/draft-next/properties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/properties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,167 @@ +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + }, + { + "description": "properties with boolean schema", + "schema": { + "properties": { + "foo": true, + "bar": false + } + }, + "tests": [ + { + "description": "no property present is valid", + "data": {}, + "valid": true + }, + { + "description": "only 'true' property present is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "only 'false' property present is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "both properties present is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + } + ] + }, + { + "description": "properties with escaped characters", + "schema": { + "properties": { + "foo\nbar": {"type": "number"}, + "foo\"bar": {"type": "number"}, + "foo\\bar": {"type": "number"}, + "foo\rbar": {"type": "number"}, + "foo\tbar": {"type": "number"}, + "foo\fbar": {"type": "number"} + } + }, + "tests": [ + { + "description": "object with all numbers is valid", + "data": { + "foo\nbar": 1, + "foo\"bar": 1, + "foo\\bar": 1, + "foo\rbar": 1, + "foo\tbar": 1, + "foo\fbar": 1 + }, + "valid": true + }, + { + "description": "object with strings is invalid", + "data": { + "foo\nbar": "1", + "foo\"bar": "1", + "foo\\bar": "1", + "foo\rbar": "1", + "foo\tbar": "1", + "foo\fbar": "1" + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/propertyNames.json python-jsonschema-4.6.0/json/tests/draft-next/propertyNames.json --- python-jsonschema-3.2.0/json/tests/draft-next/propertyNames.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/propertyNames.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,78 @@ +[ + { + "description": "propertyNames validation", + "schema": { + "propertyNames": {"maxLength": 3} + }, + "tests": [ + { + "description": "all property names valid", + "data": { + "f": {}, + "foo": {} + }, + "valid": true + }, + { + "description": "some property names invalid", + "data": { + "foo": {}, + "foobar": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [1, 2, 3, 4], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "propertyNames with boolean schema true", + "schema": {"propertyNames": true}, + "tests": [ + { + "description": "object with any properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with boolean schema false", + "schema": {"propertyNames": false}, + "tests": [ + { + "description": "object with any properties is invalid", + "data": {"foo": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/ref.json python-jsonschema-4.6.0/json/tests/draft-next/ref.json --- python-jsonschema-3.2.0/json/tests/draft-next/ref.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,581 @@ +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "prefixItems": [ + {"type": "integer"}, + {"$ref": "#/prefixItems/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "$defs": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, + "properties": { + "tilde": {"$ref": "#/$defs/tilde~0field"}, + "slash": {"$ref": "#/$defs/slash~1field"}, + "percent": {"$ref": "#/$defs/percent%25field"} + } + }, + "tests": [ + { + "description": "slash invalid", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, + "valid": false + }, + { + "description": "percent invalid", + "data": {"percent": "aoeu"}, + "valid": false + }, + { + "description": "slash valid", + "data": {"slash": 123}, + "valid": true + }, + { + "description": "tilde valid", + "data": {"tilde": 123}, + "valid": true + }, + { + "description": "percent valid", + "data": {"percent": 123}, + "valid": true + } + ] + }, + { + "description": "nested refs", + "schema": { + "$defs": { + "a": {"type": "integer"}, + "b": {"$ref": "#/$defs/a"}, + "c": {"$ref": "#/$defs/b"} + }, + "$ref": "#/$defs/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref applies alongside sibling keywords", + "schema": { + "$defs": { + "reffed": { + "type": "array" + } + }, + "properties": { + "foo": { + "$ref": "#/$defs/reffed", + "maxItems": 2 + } + } + }, + "tests": [ + { + "description": "ref valid, maxItems valid", + "data": { "foo": [] }, + "valid": true + }, + { + "description": "ref valid, maxItems invalid", + "data": { "foo": [1, 2, 3] }, + "valid": false + }, + { + "description": "ref invalid", + "data": { "foo": "string" }, + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": { + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "remote ref valid", + "data": {"minLength": 1}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"minLength": -1}, + "valid": false + } + ] + }, + { + "description": "property named $ref that is not a reference", + "schema": { + "properties": { + "$ref": {"type": "string"} + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/$defs/is-string"} + }, + "$defs": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { + "description": "$ref to boolean schema true", + "schema": { + "$ref": "#/$defs/bool", + "$defs": { + "bool": true + } + }, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "$ref to boolean schema false", + "schema": { + "$ref": "#/$defs/bool", + "$defs": { + "bool": false + } + }, + "tests": [ + { + "description": "any value is invalid", + "data": "foo", + "valid": false + } + ] + }, + { + "description": "Recursive references between schemas", + "schema": { + "$id": "http://localhost:1234/tree", + "description": "tree of nodes", + "type": "object", + "properties": { + "meta": {"type": "string"}, + "nodes": { + "type": "array", + "items": {"$ref": "node"} + } + }, + "required": ["meta", "nodes"], + "$defs": { + "node": { + "$id": "http://localhost:1234/node", + "description": "node", + "type": "object", + "properties": { + "value": {"type": "number"}, + "subtree": {"$ref": "tree"} + }, + "required": ["value"] + } + } + }, + "tests": [ + { + "description": "valid tree", + "data": { + "meta": "root", + "nodes": [ + { + "value": 1, + "subtree": { + "meta": "child", + "nodes": [ + {"value": 1.1}, + {"value": 1.2} + ] + } + }, + { + "value": 2, + "subtree": { + "meta": "child", + "nodes": [ + {"value": 2.1}, + {"value": 2.2} + ] + } + } + ] + }, + "valid": true + }, + { + "description": "invalid tree", + "data": { + "meta": "root", + "nodes": [ + { + "value": 1, + "subtree": { + "meta": "child", + "nodes": [ + {"value": "string is invalid"}, + {"value": 1.2} + ] + } + }, + { + "value": 2, + "subtree": { + "meta": "child", + "nodes": [ + {"value": 2.1}, + {"value": 2.2} + ] + } + } + ] + }, + "valid": false + } + ] + }, + { + "description": "refs with quote", + "schema": { + "properties": { + "foo\"bar": {"$ref": "#/$defs/foo%22bar"} + }, + "$defs": { + "foo\"bar": {"type": "number"} + } + }, + "tests": [ + { + "description": "object with numbers is valid", + "data": { + "foo\"bar": 1 + }, + "valid": true + }, + { + "description": "object with strings is invalid", + "data": { + "foo\"bar": "1" + }, + "valid": false + } + ] + }, + { + "description": "ref creates new scope when adjacent to keywords", + "schema": { + "$defs": { + "A": { + "unevaluatedProperties": false + } + }, + "properties": { + "prop1": { + "type": "string" + } + }, + "$ref": "#/$defs/A" + }, + "tests": [ + { + "description": "referenced subschema doesn't see annotations from properties", + "data": { + "prop1": "match" + }, + "valid": false + } + ] + }, + { + "description": "naive replacement of $ref with its destination is not correct", + "schema": { + "$defs": { + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/$defs/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "do not evaluate the $ref inside the enum, definition exact match", + "data": { "type": "string" }, + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/$defs/a_string" }, + "valid": true + } + ] + }, + { + "description": "refs with relative uris and defs", + "schema": { + "$id": "http://example.com/schema-relative-uri-defs1.json", + "properties": { + "foo": { + "$id": "schema-relative-uri-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-relative-uri-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "relative refs with absolute uris and defs", + "schema": { + "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", + "properties": { + "foo": { + "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-refs-absolute-uris-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "$id must be resolved against nearest parent, not just immediate parent", + "schema": { + "$id": "http://example.com/a.json", + "$defs": { + "x": { + "$id": "http://example.com/b/c.json", + "not": { + "$defs": { + "y": { + "$id": "d.json", + "type": "number" + } + } + } + } + }, + "allOf": [ + { + "$ref": "http://example.com/b/d.json" + } + ] + }, + "tests": [ + { + "description": "number should pass", + "data": 1, + "valid": true + }, + { + "description": "non-number should fail", + "data": "a", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/refRemote.json python-jsonschema-4.6.0/json/tests/draft-next/refRemote.json --- python-jsonschema-3.2.0/json/tests/draft-next/refRemote.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,190 @@ +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "base URI change", + "schema": { + "$id": "http://localhost:1234/", + "items": { + "$id": "baseUriChange/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "base URI change ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "base URI change ref invalid", + "data": [["a"]], + "valid": false + } + ] + }, + { + "description": "base URI change - change folder", + "schema": { + "$id": "http://localhost:1234/scope_change_defs1.json", + "type" : "object", + "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, + "$defs": { + "baz": { + "$id": "baseUriChangeFolder/", + "type": "array", + "items": {"$ref": "folderInteger.json"} + } + } + }, + "tests": [ + { + "description": "number is valid", + "data": {"list": [1]}, + "valid": true + }, + { + "description": "string is invalid", + "data": {"list": ["a"]}, + "valid": false + } + ] + }, + { + "description": "base URI change - change folder in subschema", + "schema": { + "$id": "http://localhost:1234/scope_change_defs2.json", + "type" : "object", + "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, + "$defs": { + "baz": { + "$id": "baseUriChangeFolderInSubschema/", + "$defs": { + "bar": { + "type": "array", + "items": {"$ref": "folderInteger.json"} + } + } + } + } + }, + "tests": [ + { + "description": "number is valid", + "data": {"list": [1]}, + "valid": true + }, + { + "description": "string is invalid", + "data": {"list": ["a"]}, + "valid": false + } + ] + }, + { + "description": "root ref in remote ref", + "schema": { + "$id": "http://localhost:1234/object", + "type": "object", + "properties": { + "name": {"$ref": "name-defs.json#/$defs/orNull"} + } + }, + "tests": [ + { + "description": "string is valid", + "data": { + "name": "foo" + }, + "valid": true + }, + { + "description": "null is valid", + "data": { + "name": null + }, + "valid": true + }, + { + "description": "object is invalid", + "data": { + "name": { + "name": null + } + }, + "valid": false + } + ] + }, + { + "description": "remote ref with ref to defs", + "schema": { + "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", + "$ref": "ref-and-defs.json" + }, + "tests": [ + { + "description": "invalid", + "data": { + "bar": 1 + }, + "valid": false + }, + { + "description": "valid", + "data": { + "bar": "a" + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/required.json python-jsonschema-4.6.0/json/tests/draft-next/required.json --- python-jsonschema-3.2.0/json/tests/draft-next/required.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/required.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,105 @@ +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": ["foo"] + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + }, + { + "description": "required with empty array", + "schema": { + "properties": { + "foo": {} + }, + "required": [] + }, + "tests": [ + { + "description": "property not required", + "data": {}, + "valid": true + } + ] + }, + { + "description": "required with escaped characters", + "schema": { + "required": [ + "foo\nbar", + "foo\"bar", + "foo\\bar", + "foo\rbar", + "foo\tbar", + "foo\fbar" + ] + }, + "tests": [ + { + "description": "object with all properties present is valid", + "data": { + "foo\nbar": 1, + "foo\"bar": 1, + "foo\\bar": 1, + "foo\rbar": 1, + "foo\tbar": 1, + "foo\fbar": 1 + }, + "valid": true + }, + { + "description": "object with some properties missing is invalid", + "data": { + "foo\nbar": "1", + "foo\"bar": "1" + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/type.json python-jsonschema-4.6.0/json/tests/draft-next/type.json --- python-jsonschema-3.2.0/json/tests/draft-next/type.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,474 @@ +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float with zero fractional part is an integer", + "data": 1.0, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "a string is still not an integer, even if it looks like one", + "data": "1", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float with zero fractional part is a number (and an integer)", + "data": 1.0, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "a string is still not a number, even if it looks like one", + "data": "1", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "a string is still a string, even if it looks like a number", + "data": "1", + "valid": true + }, + { + "description": "an empty string is still a string", + "data": "", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "zero is not a boolean", + "data": 0, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an empty string is not a boolean", + "data": "", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "true is a boolean", + "data": true, + "valid": true + }, + { + "description": "false is a boolean", + "data": false, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "zero is not null", + "data": 0, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an empty string is not null", + "data": "", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "true is not null", + "data": true, + "valid": false + }, + { + "description": "false is not null", + "data": false, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": "type as array with one item", + "schema": { + "type": ["string"] + }, + "tests": [ + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "number is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "type: array or object", + "schema": { + "type": ["array", "object"] + }, + "tests": [ + { + "description": "array is valid", + "data": [1,2,3], + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": 123}, + "valid": true + }, + { + "description": "number is invalid", + "data": 123, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": "type: array, object or null", + "schema": { + "type": ["array", "object", "null"] + }, + "tests": [ + { + "description": "array is valid", + "data": [1,2,3], + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": 123}, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is invalid", + "data": 123, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/unevaluatedItems.json python-jsonschema-4.6.0/json/tests/draft-next/unevaluatedItems.json --- python-jsonschema-3.2.0/json/tests/draft-next/unevaluatedItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/unevaluatedItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,633 @@ +[ + { + "description": "unevaluatedItems true", + "schema": { + "type": "array", + "unevaluatedItems": true + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems false", + "schema": { + "type": "array", + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems as schema", + "schema": { + "type": "array", + "unevaluatedItems": { "type": "string" } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with valid unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with invalid unevaluated items", + "data": [42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with uniform items", + "schema": { + "type": "array", + "items": { "type": "string" }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", "bar"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with tuple", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with items", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "items": true, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested tuple", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "allOf": [ + { + "prefixItems": [ + true, + { "type": "number" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", 42], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", 42, true], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with nested items", + "schema": { + "type": "array", + "allOf": [ + { + "prefixItems": [ + { "type": "string" } + ], + "items": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested unevaluatedItems", + "schema": { + "type": "array", + "allOf": [ + { + "prefixItems": [ + { "type": "string" } + ] + }, + { + "unevaluatedItems": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with anyOf", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "anyOf": [ + { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + { + "prefixItems": [ + true, + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when one schema matches and has no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "when one schema matches and has unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + }, + { + "description": "when two schemas match and has no unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "when two schemas match and has unevaluated items", + "data": ["foo", "bar", "baz", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with oneOf", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "oneOf": [ + { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + { + "prefixItems": [ + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with not", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "not": { + "not": { + "prefixItems": [ + true, + { "const": "bar" } + ] + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with if/then/else", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "if": { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + "then": { + "prefixItems": [ + true, + true, + { "const": "then" } + ] + }, + "else": { + "prefixItems": [ + true, + true, + true, + { "const": "else" } + ] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when if matches and it has no unevaluated items", + "data": ["foo", "bar", "then"], + "valid": true + }, + { + "description": "when if matches and it has unevaluated items", + "data": ["foo", "bar", "then", "else"], + "valid": false + }, + { + "description": "when if doesn't match and it has no unevaluated items", + "data": ["foo", 42, 42, "else"], + "valid": true + }, + { + "description": "when if doesn't match and it has unevaluated items", + "data": ["foo", 42, 42, "else", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with boolean schemas", + "schema": { + "type": "array", + "allOf": [true], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $ref", + "schema": { + "type": "array", + "$ref": "#/$defs/bar", + "prefixItems": [ + { "type": "string" } + ], + "unevaluatedItems": false, + "$defs": { + "bar": { + "prefixItems": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems can't see inside cousins", + "schema": { + "allOf": [ + { + "prefixItems": [ true ] + }, + { + "unevaluatedItems": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": [ 1 ], + "valid": false + } + ] + }, + { + "description": "item is evaluated in an uncle schema to unevaluatedItems", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "prefixItems": [ + { + "type": "string" + } + ], + "unevaluatedItems": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "prefixItems": [ + true, + { + "type": "string" + } + ] + } + } + } + ] + }, + "tests": [ + { + "description": "no extra items", + "data": { + "foo": [ + "test" + ] + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": [ + "test", + "test" + ] + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedItems depends on adjacent contains", + "schema": { + "prefixItems": [true], + "contains": {"type": "string"}, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "second item is evaluated by contains", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "contains fails, second item is not evaluated", + "data": [ 1, 2 ], + "valid": false + }, + { + "description": "contains passes, second item is not evaluated", + "data": [ 1, 2, "foo" ], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems depends on multiple nested contains", + "schema": { + "allOf": [ + { "contains": { "multipleOf": 2 } }, + { "contains": { "multipleOf": 3 } } + ], + "unevaluatedItems": { "multipleOf": 5 } + }, + "tests": [ + { + "description": "5 not evaluated, passes unevaluatedItems", + "data": [ 2, 3, 4, 5, 6 ], + "valid": true + }, + { + "description": "7 not evaluated, fails unevaluatedItems", + "data": [ 2, 3, 4, 7, 8 ], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems and contains interact to control item dependency relationship", + "schema": { + "if": { + "contains": {"const": "a"} + }, + "then": { + "if": { + "contains": {"const": "b"} + }, + "then": { + "if": { + "contains": {"const": "c"} + } + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "empty array is valid", + "data": [], + "valid": true + }, + { + "description": "only a's are valid", + "data": [ "a", "a" ], + "valid": true + }, + { + "description": "a's and b's are valid", + "data": [ "a", "b", "a", "b", "a" ], + "valid": true + }, + { + "description": "a's, b's and c's are valid", + "data": [ "c", "a", "c", "c", "b", "a" ], + "valid": true + }, + { + "description": "only b's are invalid", + "data": [ "b", "b" ], + "valid": false + }, + { + "description": "only c's are invalid", + "data": [ "c", "c" ], + "valid": false + }, + { + "description": "only b's and c's are invalid", + "data": [ "c", "b", "c", "b", "c" ], + "valid": false + }, + { + "description": "only a's and c's are invalid", + "data": [ "c", "a", "c", "a", "c" ], + "valid": false + } + ] + }, + { + "description": "non-array instances are valid", + "schema": {"unevaluatedItems": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/unevaluatedProperties.json python-jsonschema-4.6.0/json/tests/draft-next/unevaluatedProperties.json --- python-jsonschema-3.2.0/json/tests/draft-next/unevaluatedProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/unevaluatedProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,1396 @@ +[ + { + "description": "unevaluatedProperties true", + "schema": { + "type": "object", + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties schema", + "schema": { + "type": "object", + "unevaluatedProperties": { + "type": "string", + "minLength": 3 + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with valid unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with invalid unevaluated properties", + "data": { + "foo": "fo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties false", + "schema": { + "type": "object", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent patternProperties", + "schema": { + "type": "object", + "patternProperties": { + "^foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "additionalProperties": true, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "properties": { + "bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested patternProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "patternProperties": { + "^bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "additionalProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested unevaluatedProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": { + "type": "string", + "maxLength": 2 + } + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with anyOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "anyOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + }, + { + "properties": { + "quux": { "const": "quux" } + }, + "required": ["quux"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when one matches and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when one matches and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "not-baz" + }, + "valid": false + }, + { + "description": "when two match and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": true + }, + { + "description": "when two match and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz", + "quux": "not-quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with oneOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "oneOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "quux": "quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with not", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "not": { + "not": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, then not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": false + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, else not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with dependentSchemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with boolean schemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [true], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $ref", + "schema": { + "type": "object", + "$ref": "#/$defs/bar", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false, + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties can't see inside cousins", + "schema": { + "allOf": [ + { + "properties": { + "foo": true + } + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": { + "foo": 1 + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, true with properties", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, false with properties", + "schema": { + "type": "object", + "allOf": [ + { + "unevaluatedProperties": true + }, + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "property is evaluated in an uncle schema to unevaluatedProperties", + "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + }, + "unevaluatedProperties": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "properties": { + "faz": { + "type": "string" + } + } + } + } + } + ] + }, + "tests": [ + { + "description": "no extra properties", + "data": { + "foo": { + "bar": "test" + } + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": { + "bar": "test", + "faz": "test" + } + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, allOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + }, + "unevaluatedProperties": false + } + ], + "anyOf": [ + { + "properties": { + "bar": true + } + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": true + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, anyOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + } + } + ], + "anyOf": [ + { + "properties": { + "bar": true + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties + single cyclic ref", + "schema": { + "type": "object", + "properties": { + "x": { "$ref": "#" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is valid", + "data": {}, + "valid": true + }, + { + "description": "Single is valid", + "data": { "x": {} }, + "valid": true + }, + { + "description": "Unevaluated on 1st level is invalid", + "data": { "x": {}, "y": {} }, + "valid": false + }, + { + "description": "Nested is valid", + "data": { "x": { "x": {} } }, + "valid": true + }, + { + "description": "Unevaluated on 2nd level is invalid", + "data": { "x": { "x": {}, "y": {} } }, + "valid": false + }, + { + "description": "Deep nested is valid", + "data": { "x": { "x": { "x": {} } } }, + "valid": true + }, + { + "description": "Unevaluated on 3rd level is invalid", + "data": { "x": { "x": { "x": {}, "y": {} } } }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties + ref inside allOf / oneOf", + "schema": { + "$defs": { + "one": { + "properties": { "a": true } + }, + "two": { + "required": ["x"], + "properties": { "x": true } + } + }, + "allOf": [ + { "$ref": "#/$defs/one" }, + { "properties": { "b": true } }, + { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { + "required": ["y"], + "properties": { "y": true } + } + ] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid (no x or y)", + "data": {}, + "valid": false + }, + { + "description": "a and b are invalid (no x or y)", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "x and y are invalid", + "data": { "x": 1, "y": 1 }, + "valid": false + }, + { + "description": "a and x are valid", + "data": { "a": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and y are valid", + "data": { "a": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x are valid", + "data": { "a": 1, "b": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and b and y are valid", + "data": { "a": 1, "b": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x and y are invalid", + "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, + "valid": false + } + ] + }, + { + "description": "dynamic evalation inside nested refs", + "schema": { + "$defs": { + "one": { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { "required": ["b"], "properties": { "b": true } }, + { "required": ["xx"], "patternProperties": { "x": true } }, + { "required": ["all"], "unevaluatedProperties": true } + ] + }, + "two": { + "oneOf": [ + { "required": ["c"], "properties": { "c": true } }, + { "required": ["d"], "properties": { "d": true } } + ] + } + }, + "oneOf": [ + { "$ref": "#/$defs/one" }, + { "required": ["a"], "properties": { "a": true } } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid", + "data": {}, + "valid": false + }, + { + "description": "a is valid", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "b is valid", + "data": { "b": 1 }, + "valid": true + }, + { + "description": "c is valid", + "data": { "c": 1 }, + "valid": true + }, + { + "description": "d is valid", + "data": { "d": 1 }, + "valid": true + }, + { + "description": "a + b is invalid", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "a + c is invalid", + "data": { "a": 1, "c": 1 }, + "valid": false + }, + { + "description": "a + d is invalid", + "data": { "a": 1, "d": 1 }, + "valid": false + }, + { + "description": "b + c is invalid", + "data": { "b": 1, "c": 1 }, + "valid": false + }, + { + "description": "b + d is invalid", + "data": { "b": 1, "d": 1 }, + "valid": false + }, + { + "description": "c + d is invalid", + "data": { "c": 1, "d": 1 }, + "valid": false + }, + { + "description": "xx is valid", + "data": { "xx": 1 }, + "valid": true + }, + { + "description": "xx + foox is valid", + "data": { "xx": 1, "foox": 1 }, + "valid": true + }, + { + "description": "xx + foo is invalid", + "data": { "xx": 1, "foo": 1 }, + "valid": false + }, + { + "description": "xx + a is invalid", + "data": { "xx": 1, "a": 1 }, + "valid": false + }, + { + "description": "xx + b is invalid", + "data": { "xx": 1, "b": 1 }, + "valid": false + }, + { + "description": "xx + c is invalid", + "data": { "xx": 1, "c": 1 }, + "valid": false + }, + { + "description": "xx + d is invalid", + "data": { "xx": 1, "d": 1 }, + "valid": false + }, + { + "description": "all is valid", + "data": { "all": 1 }, + "valid": true + }, + { + "description": "all + foo is valid", + "data": { "all": 1, "foo": 1 }, + "valid": true + }, + { + "description": "all + a is invalid", + "data": { "all": 1, "a": 1 }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties depends on adjacent contains", + "schema": { + "properties": { + "foo": { "type": "number" } + }, + "contains": { "type": "string" }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "bar is evaluated by contains", + "data": { "foo": 1, "bar": "foo" }, + "valid": true + }, + { + "description": "contains fails, bar is not evaluated", + "data": { "foo": 1, "bar": 2 }, + "valid": false + }, + { + "description": "contains passes, bar is not evaluated", + "data": { "foo": 1, "bar": 2, "baz": "foo" }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties depends on multiple nested contains", + "schema": { + "allOf": [ + { "contains": { "multipleOf": 2 } }, + { "contains": { "multipleOf": 3 } } + ], + "unevaluatedProperties": { "multipleOf": 5 } + }, + "tests": [ + { + "description": "5 not evaluated, passes unevaluatedItems", + "data": { "a": 2, "b": 3, "c": 4, "d": 5, "e": 6 }, + "valid": true + }, + { + "description": "7 not evaluated, fails unevaluatedItems", + "data": { "a": 2, "b": 3, "c": 4, "d": 7, "e": 8 }, + "valid": false + } + ] + }, + { + "description": "non-object instances are valid", + "schema": {"unevaluatedProperties": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/uniqueItems.json python-jsonschema-4.6.0/json/tests/draft-next/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/draft-next/uniqueItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,404 @@ +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1, "{}"], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true + } + ] + }, + { + "description": "uniqueItems with an array of items", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is not valid", + "data": [false, true, "foo", "foo"], + "valid": false + }, + { + "description": "non-unique array extended from [true, false] is not valid", + "data": [true, false, "foo", "foo"], + "valid": false + } + ] + }, + { + "description": "uniqueItems with an array of items and additionalItems=false", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "items": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is not valid", + "data": [false, false], + "valid": false + }, + { + "description": "[true, true] from items array is not valid", + "data": [true, true], + "valid": false + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "items": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/unknownKeyword.json python-jsonschema-4.6.0/json/tests/draft-next/unknownKeyword.json --- python-jsonschema-3.2.0/json/tests/draft-next/unknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/unknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,56 @@ +[ + { + "description": "$id inside an unknown keyword is not a real identifier", + "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", + "schema": { + "$defs": { + "id_in_unknown0": { + "not": { + "array_of_schemas": [ + { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "null" + } + ] + } + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "string" + }, + "id_in_unknown1": { + "not": { + "object_of_schemas": { + "foo": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "integer" + } + } + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_unknown0" }, + { "$ref": "#/$defs/id_in_unknown1" }, + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "type matches second anyOf, which has a real schema in it", + "data": "a string", + "valid": true + }, + { + "description": "type matches non-schema in first anyOf", + "data": null, + "valid": false + }, + { + "description": "type matches non-schema in third anyOf", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/draft-next/vocabulary.json python-jsonschema-4.6.0/json/tests/draft-next/vocabulary.json --- python-jsonschema-3.2.0/json/tests/draft-next/vocabulary.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/draft-next/vocabulary.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "schema that uses custom metaschema with with no validation vocabulary", + "schema": { + "$id": "https://schema/using/no/validation", + "$schema": "http://localhost:1234/draft-next/metaschema-no-validation.json", + "properties": { + "badProperty": false, + "numberProperty": { + "minimum": 10 + } + } + }, + "tests": [ + { + "description": "applicator vocabulary still works", + "data": { + "badProperty": "this property should not exist" + }, + "valid": false + }, + { + "description": "no validation: valid number", + "data": { + "numberProperty": 20 + }, + "valid": true + }, + { + "description": "no validation: invalid number, but it still validates", + "data": { + "numberProperty": 1 + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/additionalItems.json python-jsonschema-4.6.0/json/tests/latest/additionalItems.json --- python-jsonschema-3.2.0/json/tests/latest/additionalItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/additionalItems.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -[ - { - "description": "additionalItems as schema", - "schema": { - "items": [{}], - "additionalItems": {"type": "integer"} - }, - "tests": [ - { - "description": "additional items match schema", - "data": [ null, 2, 3, 4 ], - "valid": true - }, - { - "description": "additional items do not match schema", - "data": [ null, 2, 3, "foo" ], - "valid": false - } - ] - }, - { - "description": "items is schema, no additionalItems", - "schema": { - "items": {}, - "additionalItems": false - }, - "tests": [ - { - "description": "all items match schema", - "data": [ 1, 2, 3, 4, 5 ], - "valid": true - } - ] - }, - { - "description": "array of items with no additionalItems", - "schema": { - "items": [{}, {}, {}], - "additionalItems": false - }, - "tests": [ - { - "description": "fewer number of items present", - "data": [ 1, 2 ], - "valid": true - }, - { - "description": "equal number of items present", - "data": [ 1, 2, 3 ], - "valid": true - }, - { - "description": "additional items are not permitted", - "data": [ 1, 2, 3, 4 ], - "valid": false - } - ] - }, - { - "description": "additionalItems as false without items", - "schema": {"additionalItems": false}, - "tests": [ - { - "description": - "items defaults to empty schema so everything is valid", - "data": [ 1, 2, 3, 4, 5 ], - "valid": true - }, - { - "description": "ignores non-arrays", - "data": {"foo" : "bar"}, - "valid": true - } - ] - }, - { - "description": "additionalItems are allowed by default", - "schema": {"items": [{"type": "integer"}]}, - "tests": [ - { - "description": "only the first item is validated", - "data": [1, "foo", false], - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/latest/additionalProperties.json python-jsonschema-4.6.0/json/tests/latest/additionalProperties.json --- python-jsonschema-3.2.0/json/tests/latest/additionalProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/additionalProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -124,7 +124,7 @@ }, "tests": [ { - "description": "properties defined in allOf are not allowed", + "description": "properties defined in allOf are not examined", "data": {"foo": 1, "bar": true}, "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/latest/allOf.json python-jsonschema-4.6.0/json/tests/latest/allOf.json --- python-jsonschema-3.2.0/json/tests/latest/allOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/allOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -214,5 +214,81 @@ "valid": false } ] + }, + { + "description": "nested allOf, to check validation semantics", + "schema": { + "allOf": [ + { + "allOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] + }, + { + "description": "allOf combined with anyOf, oneOf", + "schema": { + "allOf": [ { "multipleOf": 2 } ], + "anyOf": [ { "multipleOf": 3 } ], + "oneOf": [ { "multipleOf": 5 } ] + }, + "tests": [ + { + "description": "allOf: false, anyOf: false, oneOf: false", + "data": 1, + "valid": false + }, + { + "description": "allOf: false, anyOf: false, oneOf: true", + "data": 5, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: false", + "data": 3, + "valid": false + }, + { + "description": "allOf: false, anyOf: true, oneOf: true", + "data": 15, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: false", + "data": 2, + "valid": false + }, + { + "description": "allOf: true, anyOf: false, oneOf: true", + "data": 10, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: false", + "data": 6, + "valid": false + }, + { + "description": "allOf: true, anyOf: true, oneOf: true", + "data": 30, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/anchor.json python-jsonschema-4.6.0/json/tests/latest/anchor.json --- python-jsonschema-3.2.0/json/tests/latest/anchor.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/anchor.json 2022-06-01 20:26:26.000000000 +0000 @@ -2,9 +2,7 @@ { "description": "Location-independent identifier", "schema": { - "allOf": [{ - "$ref": "#foo" - }], + "$ref": "#foo", "$defs": { "A": { "$anchor": "foo", @@ -28,9 +26,7 @@ { "description": "Location-independent identifier with absolute URI", "schema": { - "allOf": [{ - "$ref": "http://localhost:1234/bar#foo" - }], + "$ref": "http://localhost:1234/bar#foo", "$defs": { "A": { "$id": "http://localhost:1234/bar", @@ -56,9 +52,7 @@ "description": "Location-independent identifier with base URI change in subschema", "schema": { "$id": "http://localhost:1234/root", - "allOf": [{ - "$ref": "http://localhost:1234/nested.json#foo" - }], + "$ref": "http://localhost:1234/nested.json#foo", "$defs": { "A": { "$id": "nested.json", @@ -83,5 +77,97 @@ "valid": false } ] + }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, + { + "description": "same $anchor with different base uri", + "schema": { + "$id": "http://localhost:1234/foobar", + "$defs": { + "A": { + "$id": "child1", + "allOf": [ + { + "$id": "child2", + "$anchor": "my_anchor", + "type": "number" + }, + { + "$anchor": "my_anchor", + "type": "string" + } + ] + } + }, + "$ref": "child1#my_anchor" + }, + "tests": [ + { + "description": "$ref should resolve to /$defs/A/allOf/1", + "data": "a", + "valid": true + }, + { + "description": "$ref should not resolve to /$defs/A/allOf/0", + "data": 1, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/const.json python-jsonschema-4.6.0/json/tests/latest/const.json --- python-jsonschema-3.2.0/json/tests/latest/const.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/const.json 2022-06-01 20:26:26.000000000 +0000 @@ -126,7 +126,91 @@ ] }, { - "description": "const with 0 does not match false", + "description": "const with [false] does not match [0]", + "schema": {"const": [false]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, + { + "description": "const with [true] does not match [1]", + "schema": {"const": [true]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, + { + "description": "const with {\"a\": false} does not match {\"a\": 0}", + "schema": {"const": {"a": false}}, + "tests": [ + { + "description": "{\"a\": false} is valid", + "data": {"a": false}, + "valid": true + }, + { + "description": "{\"a\": 0} is invalid", + "data": {"a": 0}, + "valid": false + }, + { + "description": "{\"a\": 0.0} is invalid", + "data": {"a": 0.0}, + "valid": false + } + ] + }, + { + "description": "const with {\"a\": true} does not match {\"a\": 1}", + "schema": {"const": {"a": true}}, + "tests": [ + { + "description": "{\"a\": true} is valid", + "data": {"a": true}, + "valid": true + }, + { + "description": "{\"a\": 1} is invalid", + "data": {"a": 1}, + "valid": false + }, + { + "description": "{\"a\": 1.0} is invalid", + "data": {"a": 1.0}, + "valid": false + } + ] + }, + { + "description": "const with 0 does not match other zero-like types", "schema": {"const": 0}, "tests": [ { @@ -143,6 +227,21 @@ "description": "float zero is valid", "data": 0.0, "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + }, + { + "description": "empty string is invalid", + "data": "", + "valid": false } ] }, @@ -166,5 +265,78 @@ "valid": true } ] + }, + { + "description": "const with -2.0 matches integer and float types", + "schema": {"const": -2.0}, + "tests": [ + { + "description": "integer -2 is valid", + "data": -2, + "valid": true + }, + { + "description": "integer 2 is invalid", + "data": 2, + "valid": false + }, + { + "description": "float -2.0 is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float 2.0 is invalid", + "data": 2.0, + "valid": false + }, + { + "description": "float -2.00001 is invalid", + "data": -2.00001, + "valid": false + } + ] + }, + { + "description": "float and integers are equal up to 64-bit representation limits", + "schema": {"const": 9007199254740992}, + "tests": [ + { + "description": "integer is valid", + "data": 9007199254740992, + "valid": true + }, + { + "description": "integer minus one is invalid", + "data": 9007199254740991, + "valid": false + }, + { + "description": "float is valid", + "data": 9007199254740992.0, + "valid": true + }, + { + "description": "float minus one is invalid", + "data": 9007199254740991.0, + "valid": false + } + ] + }, + { + "description": "nul characters in strings", + "schema": { "const": "hello\u0000there" }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/contains.json python-jsonschema-4.6.0/json/tests/latest/contains.json --- python-jsonschema-3.2.0/json/tests/latest/contains.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/contains.json 2022-06-01 20:26:26.000000000 +0000 @@ -89,6 +89,61 @@ "description": "empty array is invalid", "data": [], "valid": false + }, + { + "description": "non-arrays are valid", + "data": "contains does not apply to strings", + "valid": true + } + ] + }, + { + "description": "items + contains", + "schema": { + "items": { "multipleOf": 2 }, + "contains": { "multipleOf": 3 } + }, + "tests": [ + { + "description": "matches items, does not match contains", + "data": [ 2, 4, 8 ], + "valid": false + }, + { + "description": "does not match items, matches contains", + "data": [ 3, 6, 9 ], + "valid": false + }, + { + "description": "matches both items and contains", + "data": [ 6, 12 ], + "valid": true + }, + { + "description": "matches neither items nor contains", + "data": [ 1, 5 ], + "valid": false + } + ] + }, + { + "description": "contains with false if subschema", + "schema": { + "contains": { + "if": false, + "else": true + } + }, + "tests": [ + { + "description": "any non-empty array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/content.json python-jsonschema-4.6.0/json/tests/latest/content.json --- python-jsonschema-3.2.0/json/tests/latest/content.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/content.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,127 @@ +[ + { + "description": "validation of string-encoded content based on media type", + "schema": { + "contentMediaType": "application/json" + }, + "tests": [ + { + "description": "a valid JSON document", + "data": "{\"foo\": \"bar\"}", + "valid": true + }, + { + "description": "an invalid JSON document; validates true", + "data": "{:}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary string-encoding", + "schema": { + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64 string", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "an invalid base64 string (% is not a valid character); validates true", + "data": "eyJmb28iOi%iYmFyIn0K", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64" + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + }, + { + "description": "validation of binary-encoded media type documents with schema", + "schema": { + "contentMediaType": "application/json", + "contentEncoding": "base64", + "contentSchema": { "required": ["foo"], "properties": { "foo": { "type": "string" } } } + }, + "tests": [ + { + "description": "a valid base64-encoded JSON document", + "data": "eyJmb28iOiAiYmFyIn0K", + "valid": true + }, + { + "description": "another valid base64-encoded JSON document", + "data": "eyJib28iOiAyMCwgImZvbyI6ICJiYXoifQ==", + "valid": true + }, + { + "description": "an invalid base64-encoded JSON document; validates true", + "data": "eyJib28iOiAyMH0=", + "valid": true + }, + { + "description": "an empty object as a base64-encoded JSON document; validates true", + "data": "e30=", + "valid": true + }, + { + "description": "an empty array as a base64-encoded JSON document", + "data": "W10=", + "valid": true + }, + { + "description": "a validly-encoded invalid JSON document; validates true", + "data": "ezp9Cg==", + "valid": true + }, + { + "description": "an invalid base64 string that is valid JSON; validates true", + "data": "{}", + "valid": true + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/default.json python-jsonschema-4.6.0/json/tests/latest/default.json --- python-jsonschema-3.2.0/json/tests/latest/default.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/default.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,5 +45,35 @@ "valid": true } ] + }, + { + "description": "the default keyword does not do anything if the property is missing", + "schema": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "maximum": 3, + "default": 5 + } + } + }, + "tests": [ + { + "description": "an explicit property value is checked against maximum (passing)", + "data": { "alpha": 1 }, + "valid": true + }, + { + "description": "an explicit property value is checked against maximum (failing)", + "data": { "alpha": 5 }, + "valid": false + }, + { + "description": "missing properties are not filled in with the default", + "data": {}, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/defs.json python-jsonschema-4.6.0/json/tests/latest/defs.json --- python-jsonschema-3.2.0/json/tests/latest/defs.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/defs.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,19 +1,15 @@ [ { - "description": "valid definition", - "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, + "description": "validate definition against metaschema", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, "tests": [ { "description": "valid definition schema", "data": {"$defs": {"foo": {"type": "integer"}}}, "valid": true - } - ] - }, - { - "description": "invalid definition", - "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, - "tests": [ + }, { "description": "invalid definition schema", "data": {"$defs": {"foo": {"type": 1}}}, diff -Nru python-jsonschema-3.2.0/json/tests/latest/dependencies.json python-jsonschema-4.6.0/json/tests/latest/dependencies.json --- python-jsonschema-3.2.0/json/tests/latest/dependencies.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/dependencies.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -[ - { - "description": "dependencies", - "schema": { - "dependencies": {"bar": ["foo"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependant", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "with dependency", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "ignores arrays", - "data": ["bar"], - "valid": true - }, - { - "description": "ignores strings", - "data": "foobar", - "valid": true - }, - { - "description": "ignores other non-objects", - "data": 12, - "valid": true - } - ] - }, - { - "description": "dependencies with empty array", - "schema": { - "dependencies": {"bar": []} - }, - "tests": [ - { - "description": "empty object", - "data": {}, - "valid": true - }, - { - "description": "object with one property", - "data": {"bar": 2}, - "valid": true - } - ] - }, - { - "description": "multiple dependencies", - "schema": { - "dependencies": {"quux": ["foo", "bar"]} - }, - "tests": [ - { - "description": "neither", - "data": {}, - "valid": true - }, - { - "description": "nondependants", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "with dependencies", - "data": {"foo": 1, "bar": 2, "quux": 3}, - "valid": true - }, - { - "description": "missing dependency", - "data": {"foo": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing other dependency", - "data": {"bar": 1, "quux": 2}, - "valid": false - }, - { - "description": "missing both dependencies", - "data": {"quux": 1}, - "valid": false - } - ] - }, - { - "description": "multiple dependencies subschema", - "schema": { - "dependencies": { - "bar": { - "properties": { - "foo": {"type": "integer"}, - "bar": {"type": "integer"} - } - } - } - }, - "tests": [ - { - "description": "valid", - "data": {"foo": 1, "bar": 2}, - "valid": true - }, - { - "description": "no dependency", - "data": {"foo": "quux"}, - "valid": true - }, - { - "description": "wrong type", - "data": {"foo": "quux", "bar": 2}, - "valid": false - }, - { - "description": "wrong type other", - "data": {"foo": 2, "bar": "quux"}, - "valid": false - }, - { - "description": "wrong type both", - "data": {"foo": "quux", "bar": "quux"}, - "valid": false - } - ] - }, - { - "description": "dependencies with boolean subschemas", - "schema": { - "dependencies": { - "foo": true, - "bar": false - } - }, - "tests": [ - { - "description": "object with property having schema true is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with property having schema false is invalid", - "data": {"bar": 2}, - "valid": false - }, - { - "description": "object with both properties is invalid", - "data": {"foo": 1, "bar": 2}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] - }, - { - "description": "empty array of dependencies", - "schema": { - "dependencies": { - "foo": [] - } - }, - "tests": [ - { - "description": "object with property is valid", - "data": { "foo": 1 }, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "non-object is valid", - "data": 1, - "valid": true - } - ] - }, - { - "description": "dependencies with escaped characters", - "schema": { - "dependencies": { - "foo\nbar": ["foo\rbar"], - "foo\tbar": { - "minProperties": 4 - }, - "foo'bar": {"required": ["foo\"bar"]}, - "foo\"bar": ["foo'bar"] - } - }, - "tests": [ - { - "description": "valid object 1", - "data": { - "foo\nbar": 1, - "foo\rbar": 2 - }, - "valid": true - }, - { - "description": "valid object 2", - "data": { - "foo\tbar": 1, - "a": 2, - "b": 3, - "c": 4 - }, - "valid": true - }, - { - "description": "valid object 3", - "data": { - "foo'bar": 1, - "foo\"bar": 2 - }, - "valid": true - }, - { - "description": "invalid object 1", - "data": { - "foo\nbar": 1, - "foo": 2 - }, - "valid": false - }, - { - "description": "invalid object 2", - "data": { - "foo\tbar": 1, - "a": 2 - }, - "valid": false - }, - { - "description": "invalid object 3", - "data": { - "foo'bar": 1 - }, - "valid": false - }, - { - "description": "invalid object 4", - "data": { - "foo\"bar": 2 - }, - "valid": false - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/latest/dependentRequired.json python-jsonschema-4.6.0/json/tests/latest/dependentRequired.json --- python-jsonschema-3.2.0/json/tests/latest/dependentRequired.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/dependentRequired.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,142 @@ +[ + { + "description": "single dependency", + "schema": {"dependentRequired": {"bar": ["foo"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "empty dependents", + "schema": {"dependentRequired": {"bar": []}}, + "tests": [ + { + "description": "empty object", + "data": {}, + "valid": true + }, + { + "description": "object with one property", + "data": {"bar": 2}, + "valid": true + }, + { + "description": "non-object is valid", + "data": 1, + "valid": true + } + ] + }, + { + "description": "multiple dependents required", + "schema": {"dependentRequired": {"quux": ["foo", "bar"]}}, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentRequired": { + "foo\nbar": ["foo\rbar"], + "foo\"bar": ["foo'bar"] + } + }, + "tests": [ + { + "description": "CRLF", + "data": { + "foo\nbar": 1, + "foo\rbar": 2 + }, + "valid": true + }, + { + "description": "quoted quotes", + "data": { + "foo'bar": 1, + "foo\"bar": 2 + }, + "valid": true + }, + { + "description": "CRLF missing dependent", + "data": { + "foo\nbar": 1, + "foo": 2 + }, + "valid": false + }, + { + "description": "quoted quotes missing dependent", + "data": { + "foo\"bar": 2 + }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/dependentSchemas.json python-jsonschema-4.6.0/json/tests/latest/dependentSchemas.json --- python-jsonschema-3.2.0/json/tests/latest/dependentSchemas.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/dependentSchemas.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,129 @@ +[ + { + "description": "single dependency", + "schema": { + "dependentSchemas": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + }, + { + "description": "ignores arrays", + "data": ["bar"], + "valid": true + }, + { + "description": "ignores strings", + "data": "foobar", + "valid": true + }, + { + "description": "ignores other non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "boolean subschemas", + "schema": { + "dependentSchemas": { + "foo": true, + "bar": false + } + }, + "tests": [ + { + "description": "object with property having schema true is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property having schema false is invalid", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "object with both properties is invalid", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "dependencies with escaped characters", + "schema": { + "dependentSchemas": { + "foo\tbar": {"minProperties": 4}, + "foo'bar": {"required": ["foo\"bar"]} + } + }, + "tests": [ + { + "description": "quoted tab", + "data": { + "foo\tbar": 1, + "a": 2, + "b": 3, + "c": 4 + }, + "valid": true + }, + { + "description": "quoted quote", + "data": { + "foo'bar": {"foo\"bar": 1} + }, + "valid": false + }, + { + "description": "quoted tab invalid under dependent schema", + "data": { + "foo\tbar": 1, + "a": 2 + }, + "valid": false + }, + { + "description": "quoted quote invalid under dependent schema", + "data": {"foo'bar": 1}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/dynamicRef.json python-jsonschema-4.6.0/json/tests/latest/dynamicRef.json --- python-jsonschema-3.2.0/json/tests/latest/dynamicRef.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/dynamicRef.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,619 @@ +[ + { + "description": "A $dynamicRef to a $dynamicAnchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamicRef-dynamicAnchor-same-schema/root", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef to an $anchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamicRef-anchor-same-schema/root", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "foo": { + "$anchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $ref to a $dynamicAnchor in the same schema resource should behave like a normal $ref to an $anchor", + "schema": { + "$id": "https://test.json-schema.org/ref-dynamicAnchor-same-schema/root", + "type": "array", + "items": { "$ref": "#items" }, + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef should resolve to the first $dynamicAnchor still in scope that is encountered when the schema is evaluated", + "schema": { + "$id": "https://test.json-schema.org/typical-dynamic-resolution/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to satisfy the bookending requirement", + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "A $dynamicRef with intermediate scopes that don't include a matching $dynamicAnchor should not affect dynamic scope resolution", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-with-intermediate-scopes/root", + "$ref": "intermediate-scope", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "intermediate-scope": { + "$id": "intermediate-scope", + "$ref": "list" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to satisfy the bookending requirement", + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "An array of strings is valid", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "An array containing non-strings is invalid", + "data": ["foo", 42], + "valid": false + } + ] + }, + { + "description": "An $anchor with the same name as a $dynamicAnchor should not be used for dynamic scope resolution", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-ignores-anchors/root", + "$ref": "list", + "$defs": { + "foo": { + "$anchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to satisfy the bookending requirement", + "$dynamicAnchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef without a matching $dynamicAnchor in the same schema resource should behave like a normal $ref to $anchor", + "schema": { + "$id": "https://test.json-schema.org/dynamic-resolution-without-bookend/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref", + "$anchor": "items" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef with a non-matching $dynamicAnchor in the same schema resource should behave like a normal $ref to $anchor", + "schema": { + "$id": "https://test.json-schema.org/unmatched-dynamic-anchor/root", + "$ref": "list", + "$defs": { + "foo": { + "$dynamicAnchor": "items", + "type": "string" + }, + "list": { + "$id": "list", + "type": "array", + "items": { "$dynamicRef": "#items" }, + "$defs": { + "items": { + "$comment": "This is only needed to give the reference somewhere to resolve to when it behaves like $ref", + "$anchor": "items", + "$dynamicAnchor": "foo" + } + } + } + } + }, + "tests": [ + { + "description": "Any array is valid", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor should resolve to the first $dynamicAnchor in the dynamic scope", + "schema": { + "$id": "https://test.json-schema.org/relative-dynamic-reference/root", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "foo": { "const": "pass" } + }, + "$ref": "extended", + "$defs": { + "extended": { + "$id": "extended", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "bar": { "$ref": "bar" } + } + }, + "bar": { + "$id": "bar", + "type": "object", + "properties": { + "baz": { "$dynamicRef": "extended#meta" } + } + } + } + }, + "tests": [ + { + "description": "The recursive part is valid against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "pass" } + } + }, + "valid": true + }, + { + "description": "The recursive part is not valid against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "fail" } + } + }, + "valid": false + } + ] + }, + { + "description": "A $dynamicRef that initially resolves to a schema without a matching $dynamicAnchor should behave like a normal $ref to $anchor", + "schema": { + "$id": "https://test.json-schema.org/relative-dynamic-reference-without-bookend/root", + "$dynamicAnchor": "meta", + "type": "object", + "properties": { + "foo": { "const": "pass" } + }, + "$ref": "extended", + "$defs": { + "extended": { + "$id": "extended", + "$anchor": "meta", + "type": "object", + "properties": { + "bar": { "$ref": "bar" } + } + }, + "bar": { + "$id": "bar", + "type": "object", + "properties": { + "baz": { "$dynamicRef": "extended#meta" } + } + } + } + }, + "tests": [ + { + "description": "The recursive part doesn't need to validate against the root", + "data": { + "foo": "pass", + "bar": { + "baz": { "foo": "fail" } + } + }, + "valid": true + } + ] + }, + { + "description": "multiple dynamic paths to the $dynamicRef keyword", + "schema": { + "$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main", + "$defs": { + "inner": { + "$id": "inner", + "$dynamicAnchor": "foo", + "title": "inner", + "additionalProperties": { + "$dynamicRef": "#foo" + } + } + }, + "if": { + "propertyNames": { + "pattern": "^[a-m]" + } + }, + "then": { + "title": "any type of node", + "$id": "anyLeafNode", + "$dynamicAnchor": "foo", + "$ref": "inner" + }, + "else": { + "title": "integer node", + "$id": "integerNode", + "$dynamicAnchor": "foo", + "type": [ "object", "integer" ], + "$ref": "inner" + } + }, + "tests": [ + { + "description": "recurse to anyLeafNode - floats are allowed", + "data": { "alpha": 1.1 }, + "valid": true + }, + { + "description": "recurse to integerNode - floats are not allowed", + "data": { "november": 1.1 }, + "valid": false + } + ] + }, + { + "description": "after leaving a dynamic scope, it should not be used by a $dynamicRef", + "schema": { + "$id": "https://test.json-schema.org/dynamic-ref-leaving-dynamic-scope/main", + "if": { + "$id": "first_scope", + "$defs": { + "thingy": { + "$comment": "this is first_scope#thingy", + "$dynamicAnchor": "thingy", + "type": "number" + } + } + }, + "then": { + "$id": "second_scope", + "$ref": "start", + "$defs": { + "thingy": { + "$comment": "this is second_scope#thingy, the final destination of the $dynamicRef", + "$dynamicAnchor": "thingy", + "type": "null" + } + } + }, + "$defs": { + "start": { + "$comment": "this is the landing spot from $ref", + "$id": "start", + "$dynamicRef": "inner_scope#thingy" + }, + "thingy": { + "$comment": "this is the first stop for the $dynamicRef", + "$id": "inner_scope", + "$dynamicAnchor": "thingy", + "type": "string" + } + } + }, + "tests": [ + { + "description": "string matches /$defs/thingy, but the $dynamicRef does not stop here", + "data": "a string", + "valid": false + }, + { + "description": "first_scope is not in dynamic scope for the $dynamicRef", + "data": 42, + "valid": false + }, + { + "description": "/then/$defs/thingy is the final stop for the $dynamicRef", + "data": null, + "valid": true + } + ] + }, + { + "description": "strict-tree schema, guards against misspelled properties", + "schema": { + "$id": "http://localhost:1234/strict-tree.json", + "$dynamicAnchor": "node", + + "$ref": "tree.json", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "instance with misspelled field", + "data": { + "children": [{ + "daat": 1 + }] + }, + "valid": false + }, + { + "description": "instance with correct field", + "data": { + "children": [{ + "data": 1 + }] + }, + "valid": true + } + ] + }, + { + "description": "tests for implementation dynamic anchor and reference link", + "schema": { + "$id": "http://localhost:1234/strict-extendible.json", + "$ref": "extendible-dynamic-ref.json", + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + }, + { + "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.", + "schema": { + "$id": "http://localhost:1234/strict-extendible-allof-defs-first.json", + "allOf": [ + { + "$ref": "extendible-dynamic-ref.json" + }, + { + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + } + ] + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + }, + { + "description": "Tests for implementation dynamic anchor and reference link. Reference should be independent of any possible ordering.", + "schema": { + "$id": "http://localhost:1234/strict-extendible-allof-ref-first.json", + "allOf": [ + { + "$defs": { + "elements": { + "$dynamicAnchor": "elements", + "properties": { + "a": true + }, + "required": ["a"], + "additionalProperties": false + } + } + }, + { + "$ref": "extendible-dynamic-ref.json" + } + ] + }, + "tests": [ + { + "description": "incorrect parent schema", + "data": { + "a": true + }, + "valid": false + }, + { + "description": "incorrect extended schema", + "data": { + "elements": [ + { "b": 1 } + ] + }, + "valid": false + }, + { + "description": "correct extended schema", + "data": { + "elements": [ + { "a": 1 } + ] + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/enum.json python-jsonschema-4.6.0/json/tests/latest/enum.json --- python-jsonschema-3.2.0/json/tests/latest/enum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/enum.json 2022-06-01 20:26:26.000000000 +0000 @@ -33,6 +33,37 @@ "description": "objects are deep compared", "data": {"foo": false}, "valid": false + }, + { + "description": "valid object matches", + "data": {"foo": 12}, + "valid": true + }, + { + "description": "extra properties in object is invalid", + "data": {"foo": 12, "boo": 42}, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum-with-null validation", + "schema": { "enum": [6, null] }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "number is valid", + "data": 6, + "valid": true + }, + { + "description": "something else is invalid", + "data": "test", + "valid": false } ] }, @@ -53,6 +84,16 @@ "valid": true }, { + "description": "wrong foo value", + "data": {"foo":"foot", "bar":"bar"}, + "valid": false + }, + { + "description": "wrong bar value", + "data": {"foo":"foo", "bar":"bart"}, + "valid": false + }, + { "description": "missing optional property is valid", "data": {"bar":"bar"}, "valid": true @@ -175,5 +216,21 @@ "valid": true } ] + }, + { + "description": "nul characters in strings", + "schema": { "enum": [ "hello\u0000there" ] }, + "tests": [ + { + "description": "match string with nul", + "data": "hello\u0000there", + "valid": true + }, + { + "description": "do not match string lacking nul", + "data": "hellothere", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/format.json python-jsonschema-4.6.0/json/tests/latest/format.json --- python-jsonschema-3.2.0/json/tests/latest/format.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/format.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,611 +1,683 @@ [ { - "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "description": "email format", + "schema": { "format": "email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IDN e-mail addresses", - "schema": {"format": "idn-email"}, + "description": "idn-email format", + "schema": { "format": "idn-email" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of regexes", - "schema": {"format": "regex"}, + "description": "regex format", + "schema": { "format": "regex" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "description": "ipv4 format", + "schema": { "format": "ipv4" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "description": "ipv6 format", + "schema": { "format": "ipv6" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IDN hostnames", - "schema": {"format": "idn-hostname"}, + "description": "idn-hostname format", + "schema": { "format": "idn-hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of hostnames", - "schema": {"format": "hostname"}, + "description": "hostname format", + "schema": { "format": "hostname" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date strings", - "schema": {"format": "date"}, + "description": "date format", + "schema": { "format": "date" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "description": "date-time format", + "schema": { "format": "date-time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of time strings", - "schema": {"format": "time"}, + "description": "time format", + "schema": { "format": "time" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of JSON pointers", - "schema": {"format": "json-pointer"}, + "description": "json-pointer format", + "schema": { "format": "json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of relative JSON pointers", - "schema": {"format": "relative-json-pointer"}, + "description": "relative-json-pointer format", + "schema": { "format": "relative-json-pointer" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IRIs", - "schema": {"format": "iri"}, + "description": "iri format", + "schema": { "format": "iri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of IRI references", - "schema": {"format": "iri-reference"}, + "description": "iri-reference format", + "schema": { "format": "iri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URIs", - "schema": {"format": "uri"}, + "description": "uri format", + "schema": { "format": "uri" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI references", - "schema": {"format": "uri-reference"}, + "description": "uri-reference format", + "schema": { "format": "uri-reference" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", "data": null, "valid": true } ] }, { - "description": "validation of URI templates", - "schema": {"format": "uri-template"}, + "description": "uri-template format", + "schema": { "format": "uri-template" }, "tests": [ { - "description": "ignores integers", + "description": "all string formats ignore integers", "data": 12, "valid": true }, { - "description": "ignores floats", + "description": "all string formats ignore floats", "data": 13.7, "valid": true }, { - "description": "ignores objects", + "description": "all string formats ignore objects", "data": {}, "valid": true }, { - "description": "ignores arrays", + "description": "all string formats ignore arrays", "data": [], "valid": true }, { - "description": "ignores booleans", + "description": "all string formats ignore booleans", "data": false, "valid": true }, { - "description": "ignores null", + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "uuid format", + "schema": { "format": "uuid" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + } + ] + }, + { + "description": "duration format", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", "data": null, "valid": true } diff -Nru python-jsonschema-3.2.0/json/tests/latest/id.json python-jsonschema-4.6.0/json/tests/latest/id.json --- python-jsonschema-3.2.0/json/tests/latest/id.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/id.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,258 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/root", + "$ref": "http://localhost:1234/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/if-then-else.json python-jsonschema-4.6.0/json/tests/latest/if-then-else.json --- python-jsonschema-3.2.0/json/tests/latest/if-then-else.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/if-then-else.json 2022-06-01 20:26:26.000000000 +0000 @@ -184,5 +184,75 @@ "valid": true } ] + }, + { + "description": "if with boolean schema true", + "schema": { + "if": true, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema true in if always chooses the then path (valid)", + "data": "then", + "valid": true + }, + { + "description": "boolean schema true in if always chooses the then path (invalid)", + "data": "else", + "valid": false + } + ] + }, + { + "description": "if with boolean schema false", + "schema": { + "if": false, + "then": { "const": "then" }, + "else": { "const": "else" } + }, + "tests": [ + { + "description": "boolean schema false in if always chooses the else path (invalid)", + "data": "then", + "valid": false + }, + { + "description": "boolean schema false in if always chooses the else path (valid)", + "data": "else", + "valid": true + } + ] + }, + { + "description": "if appears at the end when serialized (keyword processing sequence)", + "schema": { + "then": { "const": "yes" }, + "else": { "const": "other" }, + "if": { "maxLength": 4 } + }, + "tests": [ + { + "description": "yes redirects to then and passes", + "data": "yes", + "valid": true + }, + { + "description": "other redirects to else and passes", + "data": "other", + "valid": true + }, + { + "description": "no redirects to then and fails", + "data": "no", + "valid": false + }, + { + "description": "invalid redirects to else and fails", + "data": "invalid", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/infinite-loop-detection.json python-jsonschema-4.6.0/json/tests/latest/infinite-loop-detection.json --- python-jsonschema-3.2.0/json/tests/latest/infinite-loop-detection.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/infinite-loop-detection.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,36 @@ +[ + { + "description": "evaluating the same schema location against the same data location twice is not a sign of an infinite loop", + "schema": { + "$defs": { + "int": { "type": "integer" } + }, + "allOf": [ + { + "properties": { + "foo": { + "$ref": "#/$defs/int" + } + } + }, + { + "additionalProperties": { + "$ref": "#/$defs/int" + } + } + ] + }, + "tests": [ + { + "description": "passing case", + "data": { "foo": 1 }, + "valid": true + }, + { + "description": "failing case", + "data": { "foo": "a string" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/items.json python-jsonschema-4.6.0/json/tests/latest/items.json --- python-jsonschema-3.2.0/json/tests/latest/items.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/items.json 2022-06-01 20:26:26.000000000 +0000 @@ -31,51 +31,6 @@ ] }, { - "description": "an array of schemas for items", - "schema": { - "items": [ - {"type": "integer"}, - {"type": "string"} - ] - }, - "tests": [ - { - "description": "correct types", - "data": [ 1, "foo" ], - "valid": true - }, - { - "description": "wrong types", - "data": [ "foo", 1 ], - "valid": false - }, - { - "description": "incomplete array of items", - "data": [ 1 ], - "valid": true - }, - { - "description": "array with additional items", - "data": [ 1, "foo", true ], - "valid": true - }, - { - "description": "empty array", - "data": [ ], - "valid": true - }, - { - "description": "JavaScript pseudo-array is valid", - "data": { - "0": "invalid", - "1": "valid", - "length": 2 - }, - "valid": true - } - ] - }, - { "description": "items with boolean schema (true)", "schema": {"items": true}, "tests": [ @@ -108,36 +63,13 @@ ] }, { - "description": "items with boolean schemas", - "schema": { - "items": [true, false] - }, - "tests": [ - { - "description": "array with one item is valid", - "data": [ 1 ], - "valid": true - }, - { - "description": "array with two items is invalid", - "data": [ 1, "foo" ], - "valid": false - }, - { - "description": "empty array is valid", - "data": [], - "valid": true - } - ] - }, - { "description": "items and subitems", "schema": { "$defs": { "item": { "type": "array", - "additionalItems": false, - "items": [ + "items": false, + "prefixItems": [ { "$ref": "#/$defs/sub-item" }, { "$ref": "#/$defs/sub-item" } ] @@ -148,8 +80,8 @@ } }, "type": "array", - "additionalItems": false, - "items": [ + "items": false, + "prefixItems": [ { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" }, { "$ref": "#/$defs/item" } @@ -246,5 +178,79 @@ "valid": false } ] + }, + { + "description": "prefixItems with no additional items allowed", + "schema": { + "prefixItems": [{}, {}, {}], + "items": false + }, + "tests": [ + { + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "fewer number of items present (1)", + "data": [ 1 ], + "valid": true + }, + { + "description": "fewer number of items present (2)", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "equal number of items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "items should not look in applicators, valid case", + "schema": { + "allOf": [ + { "prefixItems": [ { "minimum": 3 } ] } + ], + "items": { "minimum": 5 } + }, + "tests": [ + { + "description": "prefixItems in allOf should not constrain items, invalid case", + "data": [ 3, 5 ], + "valid": false + }, + { + "description": "prefixItems in allOf should not constrain items, valid case", + "data": [ 5, 5 ], + "valid": true + } + ] + }, + { + "description": "prefixItems validation adjusts the starting index for items", + "schema": { + "prefixItems": [ { "type": "string" } ], + "items": { "type": "integer" } + }, + "tests": [ + { + "description": "valid items", + "data": [ "x", 2, 3 ], + "valid": true + }, + { + "description": "wrong type of second item", + "data": [ "x", "y" ], + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/maxContains.json python-jsonschema-4.6.0/json/tests/latest/maxContains.json --- python-jsonschema-3.2.0/json/tests/latest/maxContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/maxContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,79 @@ +[ + { + "description": "maxContains without contains is ignored", + "schema": { + "maxContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "two items still valid against lone maxContains", + "data": [ 1, 2 ], + "valid": true + } + ] + }, + { + "description": "maxContains with contains", + "schema": { + "contains": {"const": 1}, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, valid maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "all elements match, invalid maxContains", + "data": [ 1, 1 ], + "valid": false + }, + { + "description": "some elements match, valid maxContains", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "some elements match, invalid maxContains", + "data": [ 1, 2, 1 ], + "valid": false + } + ] + }, + { + "description": "minContains < maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 1, + "maxContains": 3 + }, + "tests": [ + { + "description": "actual < minContains < maxContains", + "data": [ ], + "valid": false + }, + { + "description": "minContains < actual < maxContains", + "data": [ 1, 1 ], + "valid": true + }, + { + "description": "minContains < maxContains < actual", + "data": [ 1, 1, 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/maximum.json python-jsonschema-4.6.0/json/tests/latest/maximum.json --- python-jsonschema-3.2.0/json/tests/latest/maximum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/maximum.json 2022-06-01 20:26:26.000000000 +0000 @@ -24,5 +24,31 @@ "valid": true } ] + }, + { + "description": "maximum validation with unsigned integer", + "schema": {"maximum": 300}, + "tests": [ + { + "description": "below the maximum is invalid", + "data": 299.97, + "valid": true + }, + { + "description": "boundary point integer is valid", + "data": 300, + "valid": true + }, + { + "description": "boundary point float is valid", + "data": 300.00, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 300.5, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/maxProperties.json python-jsonschema-4.6.0/json/tests/latest/maxProperties.json --- python-jsonschema-3.2.0/json/tests/latest/maxProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/maxProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -34,5 +34,21 @@ "valid": true } ] + }, + { + "description": "maxProperties = 0 means the object is empty", + "schema": { "maxProperties": 0 }, + "tests": [ + { + "description": "no properties is valid", + "data": {}, + "valid": true + }, + { + "description": "one property is invalid", + "data": { "foo": 1 }, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/minContains.json python-jsonschema-4.6.0/json/tests/latest/minContains.json --- python-jsonschema-3.2.0/json/tests/latest/minContains.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/minContains.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,197 @@ +[ + { + "description": "minContains without contains is ignored", + "schema": { + "minContains": 1 + }, + "tests": [ + { + "description": "one item valid against lone minContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "zero items still valid against lone minContains", + "data": [], + "valid": true + } + ] + }, + { + "description": "minContains=1 with contains", + "schema": { + "contains": {"const": 1}, + "minContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "no elements match", + "data": [ 2 ], + "valid": false + }, + { + "description": "single element matches, valid minContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [ 1, 2 ], + "valid": true + }, + { + "description": "all elements match, valid minContains", + "data": [ 1, 1 ], + "valid": true + } + ] + }, + { + "description": "minContains=2 with contains", + "schema": { + "contains": {"const": 1}, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "some elements match, invalid minContains", + "data": [ 1, 2 ], + "valid": false + }, + { + "description": "all elements match, valid minContains (exactly as needed)", + "data": [ 1, 1 ], + "valid": true + }, + { + "description": "all elements match, valid minContains (more than needed)", + "data": [ 1, 1, 1 ], + "valid": true + }, + { + "description": "some elements match, valid minContains", + "data": [ 1, 2, 1 ], + "valid": true + } + ] + }, + { + "description": "maxContains = minContains", + "schema": { + "contains": {"const": 1}, + "maxContains": 2, + "minContains": 2 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "all elements match, invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "all elements match, invalid maxContains", + "data": [ 1, 1, 1 ], + "valid": false + }, + { + "description": "all elements match, valid maxContains and minContains", + "data": [ 1, 1 ], + "valid": true + } + ] + }, + { + "description": "maxContains < minContains", + "schema": { + "contains": {"const": 1}, + "maxContains": 1, + "minContains": 3 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": false + }, + { + "description": "invalid minContains", + "data": [ 1 ], + "valid": false + }, + { + "description": "invalid maxContains", + "data": [ 1, 1, 1 ], + "valid": false + }, + { + "description": "invalid maxContains and minContains", + "data": [ 1, 1 ], + "valid": false + } + ] + }, + { + "description": "minContains = 0", + "schema": { + "contains": {"const": 1}, + "minContains": 0 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "minContains = 0 makes contains always pass", + "data": [ 2 ], + "valid": true + } + ] + }, + { + "description": "minContains = 0 with maxContains", + "schema": { + "contains": {"const": 1}, + "minContains": 0, + "maxContains": 1 + }, + "tests": [ + { + "description": "empty data", + "data": [ ], + "valid": true + }, + { + "description": "not more than maxContains", + "data": [ 1 ], + "valid": true + }, + { + "description": "too many", + "data": [ 1, 1 ], + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/minimum.json python-jsonschema-4.6.0/json/tests/latest/minimum.json --- python-jsonschema-3.2.0/json/tests/latest/minimum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/minimum.json 2022-06-01 20:26:26.000000000 +0000 @@ -45,7 +45,17 @@ "valid": true }, { - "description": "below the minimum is invalid", + "description": "boundary point with float is valid", + "data": -2.0, + "valid": true + }, + { + "description": "float below the minimum is invalid", + "data": -2.0001, + "valid": false + }, + { + "description": "int below the minimum is invalid", "data": -3, "valid": false }, diff -Nru python-jsonschema-3.2.0/json/tests/latest/multipleOf.json python-jsonschema-4.6.0/json/tests/latest/multipleOf.json --- python-jsonschema-3.2.0/json/tests/latest/multipleOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/multipleOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -56,5 +56,16 @@ "valid": false } ] + }, + { + "description": "invalid instance should not raise error when float division = inf", + "schema": {"type": "integer", "multipleOf": 0.123456789}, + "tests": [ + { + "description": "always invalid, but naive implementations may raise an overflow error", + "data": 1e308, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/oneOf.json python-jsonschema-4.6.0/json/tests/latest/oneOf.json --- python-jsonschema-3.2.0/json/tests/latest/oneOf.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/oneOf.json 2022-06-01 20:26:26.000000000 +0000 @@ -202,5 +202,73 @@ "valid": false } ] + }, + { + "description": "oneOf with missing optional property", + "schema": { + "oneOf": [ + { + "properties": { + "bar": true, + "baz": true + }, + "required": ["bar"] + }, + { + "properties": { + "foo": true + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": {"bar": 8}, + "valid": true + }, + { + "description": "second oneOf valid", + "data": {"foo": "foo"}, + "valid": true + }, + { + "description": "both oneOf valid", + "data": {"foo": "foo", "bar": 8}, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": {"baz": "quux"}, + "valid": false + } + ] + }, + { + "description": "nested oneOf, to check validation semantics", + "schema": { + "oneOf": [ + { + "oneOf": [ + { + "type": "null" + } + ] + } + ] + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "anything non-null is invalid", + "data": 123, + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/bignum.json python-jsonschema-4.6.0/json/tests/latest/optional/bignum.json --- python-jsonschema-3.2.0/json/tests/latest/optional/bignum.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/bignum.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,30 +1,13 @@ [ { "description": "integer", - "schema": {"type": "integer"}, + "schema": { "type": "integer" }, "tests": [ { "description": "a bignum is an integer", "data": 12345678910111213141516171819202122232425262728293031, "valid": true - } - ] - }, - { - "description": "number", - "schema": {"type": "number"}, - "tests": [ - { - "description": "a bignum is a number", - "data": 98249283749234923498293171823948729348710298301928331, - "valid": true - } - ] - }, - { - "description": "integer", - "schema": {"type": "integer"}, - "tests": [ + }, { "description": "a negative bignum is an integer", "data": -12345678910111213141516171819202122232425262728293031, @@ -34,9 +17,14 @@ }, { "description": "number", - "schema": {"type": "number"}, + "schema": { "type": "number" }, "tests": [ { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + }, + { "description": "a negative bignum is a number", "data": -98249283749234923498293171823948729348710298301928331, "valid": true @@ -45,7 +33,7 @@ }, { "description": "string", - "schema": {"type": "string"}, + "schema": { "type": "string" }, "tests": [ { "description": "a bignum is not a string", @@ -56,7 +44,7 @@ }, { "description": "integer comparison", - "schema": {"maximum": 18446744073709551615}, + "schema": { "maximum": 18446744073709551615 }, "tests": [ { "description": "comparison works for high numbers", @@ -80,7 +68,7 @@ }, { "description": "integer comparison", - "schema": {"minimum": -18446744073709551615}, + "schema": { "minimum": -18446744073709551615 }, "tests": [ { "description": "comparison works for very negative numbers", diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/content.json python-jsonschema-4.6.0/json/tests/latest/optional/content.json --- python-jsonschema-3.2.0/json/tests/latest/optional/content.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/content.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -[ - { - "description": "validation of string-encoded content based on media type", - "schema": { - "contentMediaType": "application/json" - }, - "tests": [ - { - "description": "a valid JSON document", - "data": "{\"foo\": \"bar\"}", - "valid": true - }, - { - "description": "an invalid JSON document", - "data": "{:}", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - }, - { - "description": "validation of binary string-encoding", - "schema": { - "contentEncoding": "base64" - }, - "tests": [ - { - "description": "a valid base64 string", - "data": "eyJmb28iOiAiYmFyIn0K", - "valid": true - }, - { - "description": "an invalid base64 string (% is not a valid character)", - "data": "eyJmb28iOi%iYmFyIn0K", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - }, - { - "description": "validation of binary-encoded media type documents", - "schema": { - "contentMediaType": "application/json", - "contentEncoding": "base64" - }, - "tests": [ - { - "description": "a valid base64-encoded JSON document", - "data": "eyJmb28iOiAiYmFyIn0K", - "valid": true - }, - { - "description": "a validly-encoded invalid JSON document", - "data": "ezp9Cg==", - "valid": false - }, - { - "description": "an invalid base64 string that is valid JSON", - "data": "{}", - "valid": false - }, - { - "description": "ignores non-strings", - "data": 100, - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/ecmascript-regex.json python-jsonschema-4.6.0/json/tests/latest/optional/ecmascript-regex.json --- python-jsonschema-3.2.0/json/tests/latest/optional/ecmascript-regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/ecmascript-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,16 +1,5 @@ [ { - "description": "ECMA 262 regex non-compliance", - "schema": { "format": "regex" }, - "tests": [ - { - "description": "ECMA 262 has no support for \\Z anchor from .NET", - "data": "^\\S(|(.|\\n)*\\S)\\Z", - "valid": false - } - ] - }, - { "description": "ECMA 262 regex $ does not match trailing newline", "schema": { "type": "string", @@ -19,7 +8,7 @@ "tests": [ { "description": "matches in Python, but should not in jsonschema", - "data": "abc\n", + "data": "abc\\n", "valid": false }, { @@ -30,20 +19,20 @@ ] }, { - "description": "ECMA 262 regex converts \\a to ascii BEL", + "description": "ECMA 262 regex converts \\t to horizontal tab", "schema": { "type": "string", - "pattern": "^\\a$" + "pattern": "^\\t$" }, "tests": [ { "description": "does not match", - "data": "\\a", + "data": "\\t", "valid": false }, { "description": "matches", - "data": "\u0007", + "data": "\u0009", "valid": true } ] @@ -154,7 +143,7 @@ ] }, { - "description": "ECMA 262 \\w matches everything but ascii letters", + "description": "ECMA 262 \\W matches everything but ascii letters", "schema": { "type": "string", "pattern": "^\\W$" @@ -173,7 +162,7 @@ ] }, { - "description": "ECMA 262 \\s matches ascii whitespace only", + "description": "ECMA 262 \\s matches whitespace", "schema": { "type": "string", "pattern": "^\\s$" @@ -185,14 +174,59 @@ "valid": true }, { - "description": "latin-1 non-breaking-space does not match (unlike e.g. Python)", + "description": "Character tabulation matches", + "data": "\t", + "valid": true + }, + { + "description": "Line tabulation matches", + "data": "\u000b", + "valid": true + }, + { + "description": "Form feed matches", + "data": "\u000c", + "valid": true + }, + { + "description": "latin-1 non-breaking-space matches", "data": "\u00a0", + "valid": true + }, + { + "description": "zero-width whitespace matches", + "data": "\ufeff", + "valid": true + }, + { + "description": "line feed matches (line terminator)", + "data": "\u000a", + "valid": true + }, + { + "description": "paragraph separator matches (line terminator)", + "data": "\u2029", + "valid": true + }, + { + "description": "EM SPACE matches (Space_Separator)", + "data": "\u2003", + "valid": true + }, + { + "description": "Non-whitespace control does not match", + "data": "\u0001", + "valid": false + }, + { + "description": "Non-whitespace does not match", + "data": "\u2013", "valid": false } ] }, { - "description": "ECMA 262 \\S matches everything but ascii whitespace", + "description": "ECMA 262 \\S matches everything but whitespace", "schema": { "type": "string", "pattern": "^\\S$" @@ -204,8 +238,313 @@ "valid": false }, { - "description": "latin-1 non-breaking-space matches (unlike e.g. Python)", + "description": "Character tabulation does not match", + "data": "\t", + "valid": false + }, + { + "description": "Line tabulation does not match", + "data": "\u000b", + "valid": false + }, + { + "description": "Form feed does not match", + "data": "\u000c", + "valid": false + }, + { + "description": "latin-1 non-breaking-space does not match", "data": "\u00a0", + "valid": false + }, + { + "description": "zero-width whitespace does not match", + "data": "\ufeff", + "valid": false + }, + { + "description": "line feed does not match (line terminator)", + "data": "\u000a", + "valid": false + }, + { + "description": "paragraph separator does not match (line terminator)", + "data": "\u2029", + "valid": false + }, + { + "description": "EM SPACE does not match (Space_Separator)", + "data": "\u2003", + "valid": false + }, + { + "description": "Non-whitespace control matches", + "data": "\u0001", + "valid": true + }, + { + "description": "Non-whitespace matches", + "data": "\u2013", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all pattern matching", + "schema": { "pattern": "\\p{Letter}cole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "\\w in patterns matches [A-Za-z0-9_], not unicode letters", + "schema": { "pattern": "\\wcole" }, + "tests": [ + { + "description": "ascii character in json string", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": "LES HIVERS DE MON ENFANCE ÉTAIENT DES SAISONS LONGUES, LONGUES. NOUS VIVIONS EN TROIS LIEUX: L'ÉCOLE, L'ÉGLISE ET LA PATINOIRE; MAIS LA VRAIE VIE ÉTAIT SUR LA PATINOIRE.", + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { "pattern": "[a-z]cole" }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'école, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": "Les hivers de mon enfance étaient des saisons longues, longues. Nous vivions en trois lieux: l'\u00e9cole, l'église et la patinoire; mais la vraie vie était sur la patinoire.", + "valid": false + }, + { + "description": "ascii characters match", + "data": "Les hivers de mon enfance etaient des saisons longues, longues. Nous vivions en trois lieux: l'ecole, l'eglise et la patinoire; mais la vraie vie etait sur la patinoire.", + "valid": true + } + ] + }, + { + "description": "\\d in pattern matches [0-9], not unicode digits", + "schema": { "pattern": "^\\d+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { "pattern": "^\\p{digit}+$" }, + "tests": [ + { + "description": "ascii digits", + "data": "42", + "valid": true + }, + { + "description": "ascii non-digits", + "data": "-%#", + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": "৪২", + "valid": true + } + ] + }, + { + "description": "unicode semantics should be used for all patternProperties matching", + "schema": { + "type": "object", + "patternProperties": { + "\\p{Letter}cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "\\w in patternProperties matches [A-Za-z0-9_], not unicode letters", + "schema": { + "type": "object", + "patternProperties": { + "\\wcole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii character in json string", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + }, + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode matching is case-sensitive", + "data": { "L'ÉCOLE": "PAS DE VRAIE VIE" }, + "valid": false + } + ] + }, + { + "description": "unicode characters do not match ascii ranges", + "schema": { + "type": "object", + "patternProperties": { + "[a-z]cole": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "literal unicode character in json string", + "data": { "l'école": "pas de vraie vie" }, + "valid": false + }, + { + "description": "unicode character in hex format in string", + "data": { "l'\u00e9cole": "pas de vraie vie" }, + "valid": false + }, + { + "description": "ascii characters match", + "data": { "l'ecole": "pas de vraie vie" }, + "valid": true + } + ] + }, + { + "description": "\\d in patternProperties matches [0-9], not unicode digits", + "schema": { + "type": "object", + "patternProperties": { + "^\\d+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, + "valid": false + } + ] + }, + { + "description": "unicode digits are more than 0 through 9", + "schema": { + "type": "object", + "patternProperties": { + "^\\p{digit}+$": true + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "ascii digits", + "data": { "42": "life, the universe, and everything" }, + "valid": true + }, + { + "description": "ascii non-digits", + "data": { "-%#": "spending the year dead for tax reasons" }, + "valid": false + }, + { + "description": "non-ascii digits (BENGALI DIGIT FOUR, BENGALI DIGIT TWO)", + "data": { "৪২": "khajit has wares if you have coin" }, "valid": true } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/float-overflow.json python-jsonschema-4.6.0/json/tests/latest/optional/float-overflow.json --- python-jsonschema-3.2.0/json/tests/latest/optional/float-overflow.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/float-overflow.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,13 @@ +[ + { + "description": "all integers are multiples of 0.5, if overflow is handled", + "schema": {"type": "integer", "multipleOf": 0.5}, + "tests": [ + { + "description": "valid if optional overflow handling is implemented", + "data": 1e308, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/date.json python-jsonschema-4.6.0/json/tests/latest/optional/format/date.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/date.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/date.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,180 @@ [ { "description": "validation of date strings", - "schema": {"format": "date"}, + "schema": { "format": "date" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid date string", "data": "1963-06-19", "valid": true }, { - "description": "an invalid date-time string", + "description": "a valid date string with 31 days in January", + "data": "2020-01-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in January", + "data": "2020-01-32", + "valid": false + }, + { + "description": "a valid date string with 28 days in February (normal)", + "data": "2021-02-28", + "valid": true + }, + { + "description": "a invalid date string with 29 days in February (normal)", + "data": "2021-02-29", + "valid": false + }, + { + "description": "a valid date string with 29 days in February (leap)", + "data": "2020-02-29", + "valid": true + }, + { + "description": "a invalid date string with 30 days in February (leap)", + "data": "2020-02-30", + "valid": false + }, + { + "description": "a valid date string with 31 days in March", + "data": "2020-03-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in March", + "data": "2020-03-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in April", + "data": "2020-04-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in April", + "data": "2020-04-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in May", + "data": "2020-05-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in May", + "data": "2020-05-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in June", + "data": "2020-06-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in June", + "data": "2020-06-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in July", + "data": "2020-07-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in July", + "data": "2020-07-32", + "valid": false + }, + { + "description": "a valid date string with 31 days in August", + "data": "2020-08-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in August", + "data": "2020-08-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in September", + "data": "2020-09-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in September", + "data": "2020-09-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in October", + "data": "2020-10-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in October", + "data": "2020-10-32", + "valid": false + }, + { + "description": "a valid date string with 30 days in November", + "data": "2020-11-30", + "valid": true + }, + { + "description": "a invalid date string with 31 days in November", + "data": "2020-11-31", + "valid": false + }, + { + "description": "a valid date string with 31 days in December", + "data": "2020-12-31", + "valid": true + }, + { + "description": "a invalid date string with 32 days in December", + "data": "2020-12-32", + "valid": false + }, + { + "description": "a invalid date string with invalid month", + "data": "2020-13-01", + "valid": false + }, + { + "description": "an invalid date string", "data": "06/19/1963", "valid": false }, @@ -17,6 +182,41 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350", "valid": false + }, + { + "description": "non-padded month dates are not valid", + "data": "1998-1-20", + "valid": false + }, + { + "description": "non-padded day dates are not valid", + "data": "1998-01-1", + "valid": false + }, + { + "description": "invalid month", + "data": "1998-13-01", + "valid": false + }, + { + "description": "invalid month-day combination", + "data": "1998-04-31", + "valid": false + }, + { + "description": "2021 is not a leap year", + "data": "2021-02-29", + "valid": false + }, + { + "description": "2020 is a leap year", + "data": "2020-02-29", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1963-06-1৪", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/date-time.json python-jsonschema-4.6.0/json/tests/latest/optional/format/date-time.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/date-time.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/date-time.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of date-time strings", - "schema": {"format": "date-time"}, + "schema": { "format": "date-time" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid date-time string", "data": "1963-06-19T08:30:06.283185Z", "valid": true @@ -24,13 +54,43 @@ "valid": true }, { - "description": "a invalid day in date-time string", - "data": "1990-02-31T15:59:60.123-08:00", + "description": "a valid date-time with a leap second, UTC", + "data": "1998-12-31T23:59:60Z", + "valid": true + }, + { + "description": "a valid date-time with a leap second, with minus offset", + "data": "1998-12-31T15:59:60.123-08:00", + "valid": true + }, + { + "description": "an invalid date-time past leap second, UTC", + "data": "1998-12-31T23:59:61Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong minute, UTC", + "data": "1998-12-31T23:58:60Z", + "valid": false + }, + { + "description": "an invalid date-time with leap second on a wrong hour, UTC", + "data": "1998-12-31T22:59:60Z", + "valid": false + }, + { + "description": "an invalid day in date-time string", + "data": "1990-02-31T15:59:59.123-08:00", "valid": false }, { "description": "an invalid offset in date-time string", - "data": "1990-12-31T15:59:60-24:00", + "data": "1990-12-31T15:59:59-24:00", + "valid": false + }, + { + "description": "an invalid closing Z after time-zone offset", + "data": "1963-06-19T08:30:06.28123+01:00Z", "valid": false }, { @@ -47,6 +107,26 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "2013-350T01:01:01", "valid": false + }, + { + "description": "invalid non-padded month dates", + "data": "1963-6-19T08:30:06.283185Z", + "valid": false + }, + { + "description": "invalid non-padded day dates", + "data": "1963-06-1T08:30:06.283185Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the date portion", + "data": "1963-06-1৪T00:00:00Z", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the time portion", + "data": "1963-06-11T0৪:00:00Z", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/duration.json python-jsonschema-4.6.0/json/tests/latest/optional/format/duration.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/duration.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/duration.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,128 @@ +[ + { + "description": "validation of duration strings", + "schema": { "format": "duration" }, + "tests": [ + { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "a valid duration string", + "data": "P4DT12H30M5S", + "valid": true + }, + { + "description": "an invalid duration string", + "data": "PT1D", + "valid": false + }, + { + "description": "no elements present", + "data": "P", + "valid": false + }, + { + "description": "no time elements present", + "data": "P1YT", + "valid": false + }, + { + "description": "no date or time elements present", + "data": "PT", + "valid": false + }, + { + "description": "elements out of order", + "data": "P2D1Y", + "valid": false + }, + { + "description": "missing time separator", + "data": "P1D2H", + "valid": false + }, + { + "description": "time element in the date position", + "data": "P2S", + "valid": false + }, + { + "description": "four years duration", + "data": "P4Y", + "valid": true + }, + { + "description": "zero time, in seconds", + "data": "PT0S", + "valid": true + }, + { + "description": "zero time, in days", + "data": "P0D", + "valid": true + }, + { + "description": "one month duration", + "data": "P1M", + "valid": true + }, + { + "description": "one minute duration", + "data": "PT1M", + "valid": true + }, + { + "description": "one and a half days, in hours", + "data": "PT36H", + "valid": true + }, + { + "description": "one and a half days, in days and hours", + "data": "P1DT12H", + "valid": true + }, + { + "description": "two weeks", + "data": "P2W", + "valid": true + }, + { + "description": "weeks cannot be combined with other units", + "data": "P1Y2W", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "P২Y", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/email.json python-jsonschema-4.6.0/json/tests/latest/optional/format/email.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/email.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/email.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of e-mail addresses", - "schema": {"format": "email"}, + "schema": { "format": "email" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid e-mail address", "data": "joe.bloggs@example.com", "valid": true @@ -12,6 +42,76 @@ "description": "an invalid e-mail address", "data": "2962", "valid": false + }, + { + "description": "tilde in local part is valid", + "data": "te~st@example.com", + "valid": true + }, + { + "description": "tilde before local part is valid", + "data": "~test@example.com", + "valid": true + }, + { + "description": "tilde after local part is valid", + "data": "test~@example.com", + "valid": true + }, + { + "description": "a quoted string with a space in the local part is valid", + "data": "\"joe bloggs\"@example.com", + "valid": true + }, + { + "description": "a quoted string with a double dot in the local part is valid", + "data": "\"joe..bloggs\"@example.com", + "valid": true + }, + { + "description": "a quoted string with a @ in the local part is valid", + "data": "\"joe@bloggs\"@example.com", + "valid": true + }, + { + "description": "an IPv4-address-literal after the @ is valid", + "data": "joe.bloggs@[127.0.0.1]", + "valid": true + }, + { + "description": "an IPv6-address-literal after the @ is valid", + "data": "joe.bloggs@[IPv6:::1]", + "valid": true + }, + { + "description": "dot before local part is not valid", + "data": ".test@example.com", + "valid": false + }, + { + "description": "dot after local part is not valid", + "data": "test.@example.com", + "valid": false + }, + { + "description": "two separated dots inside local part are valid", + "data": "te.s.t@example.com", + "valid": true + }, + { + "description": "two subsequent dots inside local part are not valid", + "data": "te..st@example.com", + "valid": false + }, + { + "description": "an invalid domain", + "data": "joe.bloggs@invalid=domain.com", + "valid": false + }, + { + "description": "an invalid IPv4-address-literal", + "data": "joe.bloggs@[127.0.0.300]", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/hostname.json python-jsonschema-4.6.0/json/tests/latest/optional/format/hostname.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/hostname.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of host names", - "schema": {"format": "hostname"}, + "schema": { "format": "hostname" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid host name", "data": "www.example.com", "valid": true @@ -27,6 +57,41 @@ "description": "a host name with a component too long", "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", "valid": false + }, + { + "description": "starts with hyphen", + "data": "-hostname", + "valid": false + }, + { + "description": "ends with hyphen", + "data": "hostname-", + "valid": false + }, + { + "description": "starts with underscore", + "data": "_hostname", + "valid": false + }, + { + "description": "ends with underscore", + "data": "hostname_", + "valid": false + }, + { + "description": "contains underscore", + "data": "host_name", + "valid": false + }, + { + "description": "maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com", + "valid": true + }, + { + "description": "exceeds maximum label length", + "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/idn-email.json python-jsonschema-4.6.0/json/tests/latest/optional/format/idn-email.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/idn-email.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/idn-email.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of an internationalized e-mail addresses", - "schema": {"format": "idn-email"}, + "schema": { "format": "idn-email" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid idn e-mail (example@example.test in Hangul)", "data": "실례@실례.테스트", "valid": true @@ -12,6 +42,16 @@ "description": "an invalid idn e-mail address", "data": "2962", "valid": false + }, + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/idn-hostname.json python-jsonschema-4.6.0/json/tests/latest/optional/format/idn-hostname.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/idn-hostname.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/idn-hostname.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of internationalized host names", - "schema": {"format": "idn-hostname"}, + "schema": { "format": "idn-hostname" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid host name (example.test in Hangul)", "data": "실례.테스트", "valid": true @@ -22,6 +52,252 @@ "description": "a host name with a component too long", "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", "valid": false + }, + { + "description": "invalid label, correct Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc3492#section-7.1", + "data": "-> $1.00 <--", + "valid": false + }, + { + "description": "valid Chinese Punycode", + "comment": "https://tools.ietf.org/html/rfc5890#section-2.3.2.1 https://tools.ietf.org/html/rfc5891#section-4.4", + "data": "xn--ihqwcrb4cv8a8dqg056pqjye", + "valid": true + }, + { + "description": "invalid Punycode", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.4 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "xn--X", + "valid": false + }, + { + "description": "U-label contains \"--\" in the 3rd and 4th position", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1 https://tools.ietf.org/html/rfc5890#section-2.3.2.1", + "data": "XN--aa---o47jg78q", + "valid": false + }, + { + "description": "U-label starts with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello", + "valid": false + }, + { + "description": "U-label ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "hello-", + "valid": false + }, + { + "description": "U-label starts and ends with a dash", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.1", + "data": "-hello-", + "valid": false + }, + { + "description": "Begins with a Spacing Combining Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0903hello", + "valid": false + }, + { + "description": "Begins with a Nonspacing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0300hello", + "valid": false + }, + { + "description": "Begins with an Enclosing Mark", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", + "data": "\u0488hello", + "valid": false + }, + { + "description": "Exceptions that are PVALID, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u00df\u03c2\u0f0b\u3007", + "valid": true + }, + { + "description": "Exceptions that are PVALID, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u06fd\u06fe", + "valid": true + }, + { + "description": "Exceptions that are DISALLOWED, right-to-left chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", + "data": "\u0640\u07fa", + "valid": false + }, + { + "description": "Exceptions that are DISALLOWED, left-to-right chars", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", + "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", + "valid": false + }, + { + "description": "MIDDLE DOT with no preceding 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "a\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing preceding", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "\u00b7l", + "valid": false + }, + { + "description": "MIDDLE DOT with no following 'l'", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7a", + "valid": false + }, + { + "description": "MIDDLE DOT with nothing following", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7", + "valid": false + }, + { + "description": "MIDDLE DOT with surrounding 'l's", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", + "data": "l\u00b7l", + "valid": true + }, + { + "description": "Greek KERAIA not followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375S", + "valid": false + }, + { + "description": "Greek KERAIA not followed by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375", + "valid": false + }, + { + "description": "Greek KERAIA followed by Greek", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", + "data": "\u03b1\u0375\u03b2", + "valid": true + }, + { + "description": "Hebrew GERESH not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "A\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05f3\u05d1", + "valid": false + }, + { + "description": "Hebrew GERESH preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", + "data": "\u05d0\u05f3\u05d1", + "valid": true + }, + { + "description": "Hebrew GERSHAYIM not preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "A\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05f4\u05d1", + "valid": false + }, + { + "description": "Hebrew GERSHAYIM preceded by Hebrew", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", + "data": "\u05d0\u05f4\u05d1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "def\u30fbabc", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with no other characters", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb", + "valid": false + }, + { + "description": "KATAKANA MIDDLE DOT with Hiragana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u3041", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Katakana", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u30a1", + "valid": true + }, + { + "description": "KATAKANA MIDDLE DOT with Han", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", + "data": "\u30fb\u4e08", + "valid": true + }, + { + "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0660\u06f0", + "valid": false + }, + { + "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", + "data": "\u0628\u0660\u0628", + "valid": true + }, + { + "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", + "data": "\u06f00", + "valid": true + }, + { + "description": "ZERO WIDTH JOINER not preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER not preceded by anything", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u200d\u0937", + "valid": false + }, + { + "description": "ZERO WIDTH JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", + "data": "\u0915\u094d\u200d\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER preceded by Virama", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", + "data": "\u0915\u094d\u200c\u0937", + "valid": true + }, + { + "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", + "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", + "data": "\u0628\u064a\u200c\u0628\u064a", + "valid": true } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/ipv4.json python-jsonschema-4.6.0/json/tests/latest/optional/format/ipv4.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/ipv4.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/ipv4.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IP addresses", - "schema": {"format": "ipv4"}, + "schema": { "format": "ipv4" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IP address", "data": "192.168.0.1", "valid": true @@ -27,6 +57,27 @@ "description": "an IP address as an integer", "data": "0x7f000001", "valid": false + }, + { + "description": "an IP address as an integer (decimal)", + "data": "2130706433", + "valid": false + }, + { + "description": "leading zeroes should be rejected, as they are treated as octals", + "comment": "see https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/", + "data": "087.10.0.1", + "valid": false + }, + { + "description": "value without leading zero is valid", + "data": "87.10.0.1", + "valid": true + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২7.0.0.1", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/ipv6.json python-jsonschema-4.6.0/json/tests/latest/optional/format/ipv6.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/ipv6.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/ipv6.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IPv6 addresses", - "schema": {"format": "ipv6"}, + "schema": { "format": "ipv6" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IPv6 address", "data": "::1", "valid": true @@ -14,6 +44,16 @@ "valid": false }, { + "description": "trailing 4 hex symbols is valid", + "data": "::abef", + "valid": true + }, + { + "description": "trailing 5 hex symbols is invalid", + "data": "::abcef", + "valid": false + }, + { "description": "an IPv6 address with too many components", "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", "valid": false @@ -22,6 +62,146 @@ "description": "an IPv6 address containing illegal characters", "data": "::laptop", "valid": false + }, + { + "description": "no digits is valid", + "data": "::", + "valid": true + }, + { + "description": "leading colons is valid", + "data": "::42:ff:1", + "valid": true + }, + { + "description": "trailing colons is valid", + "data": "d6::", + "valid": true + }, + { + "description": "missing leading octet is invalid", + "data": ":2:3:4:5:6:7:8", + "valid": false + }, + { + "description": "missing trailing octet is invalid", + "data": "1:2:3:4:5:6:7:", + "valid": false + }, + { + "description": "missing leading octet with omitted octets later", + "data": ":2:3:4::8", + "valid": false + }, + { + "description": "single set of double colons in the middle is valid", + "data": "1:d6::42", + "valid": true + }, + { + "description": "two sets of double colons is invalid", + "data": "1::d6::42", + "valid": false + }, + { + "description": "mixed format with the ipv4 section as decimal octets", + "data": "1::d6:192.168.0.1", + "valid": true + }, + { + "description": "mixed format with double colons between the sections", + "data": "1:2::192.168.0.1", + "valid": true + }, + { + "description": "mixed format with ipv4 section with octet out of range", + "data": "1::2:192.168.256.1", + "valid": false + }, + { + "description": "mixed format with ipv4 section with a hex octet", + "data": "1::2:192.168.ff.1", + "valid": false + }, + { + "description": "mixed format with leading double colons (ipv4-mapped ipv6 address)", + "data": "::ffff:192.168.0.1", + "valid": true + }, + { + "description": "triple colons is invalid", + "data": "1:2:3:4:5:::8", + "valid": false + }, + { + "description": "8 octets", + "data": "1:2:3:4:5:6:7:8", + "valid": true + }, + { + "description": "insufficient octets without double colons", + "data": "1:2:3:4:5:6:7", + "valid": false + }, + { + "description": "no colons is invalid", + "data": "1", + "valid": false + }, + { + "description": "ipv4 is not ipv6", + "data": "127.0.0.1", + "valid": false + }, + { + "description": "ipv4 segment must have 4 octets", + "data": "1:2:3:4:1.2.3", + "valid": false + }, + { + "description": "leading whitespace is invalid", + "data": " ::1", + "valid": false + }, + { + "description": "trailing whitespace is invalid", + "data": "::1 ", + "valid": false + }, + { + "description": "netmask is not a part of ipv6 address", + "data": "fe80::/64", + "valid": false + }, + { + "description": "zone id is not a part of ipv6 address", + "data": "fe80::a%eth1", + "valid": false + }, + { + "description": "a long valid ipv6", + "data": "1000:1000:1000:1000:1000:1000:255.255.255.255", + "valid": true + }, + { + "description": "a long invalid ipv6, below length limit, first", + "data": "100:100:100:100:100:100:255.255.255.255.255", + "valid": false + }, + { + "description": "a long invalid ipv6, below length limit, second", + "data": "100:100:100:100:100:100:100:255.255.255.255", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1:2:3:4:5:6:7:৪", + "valid": false + }, + { + "description": "non-ascii digits should be rejected in the ipv4 portion also", + "data": "1:2::192.16৪.0.1", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/iri.json python-jsonschema-4.6.0/json/tests/latest/optional/format/iri.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/iri.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/iri.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,45 @@ [ { "description": "validation of IRIs", - "schema": {"format": "iri"}, + "schema": { "format": "iri" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IRI with anchor tag", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true }, { - "description": "a valid IRI with anchor tag and parantheses", + "description": "a valid IRI with anchor tag and parentheses", "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", "valid": true }, diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/iri-reference.json python-jsonschema-4.6.0/json/tests/latest/optional/format/iri-reference.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/iri-reference.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/iri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of IRI References", - "schema": {"format": "iri-reference"}, + "schema": { "format": "iri-reference" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid IRI", "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/json-pointer.json python-jsonschema-4.6.0/json/tests/latest/optional/format/json-pointer.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/json-pointer.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of JSON-pointers (JSON String Representation)", - "schema": {"format": "json-pointer"}, + "schema": { "format": "json-pointer" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid JSON-pointer", "data": "/foo/bar~0/baz~1/%a", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/regex.json python-jsonschema-4.6.0/json/tests/latest/optional/format/regex.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/regex.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of regular expressions", - "schema": {"format": "regex"}, + "schema": { "format": "regex" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid regular expression", "data": "([abc])+\\s+$", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/relative-json-pointer.json python-jsonschema-4.6.0/json/tests/latest/optional/format/relative-json-pointer.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/relative-json-pointer.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/relative-json-pointer.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,45 @@ [ { "description": "validation of Relative JSON Pointers (RJP)", - "schema": {"format": "relative-json-pointer"}, + "schema": { "format": "relative-json-pointer" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid upwards RJP", "data": "1", "valid": true }, { - "description": "a valid downwards RJP", + "description": "a valid downwards RJP", "data": "0/foo/bar", "valid": true }, @@ -27,6 +57,26 @@ "description": "an invalid RJP that is a valid JSON Pointer", "data": "/foo/bar", "valid": false + }, + { + "description": "negative prefix", + "data": "-1/foo/bar", + "valid": false + }, + { + "description": "## is not a valid json-pointer", + "data": "0##", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus json-pointer", + "data": "01/a", + "valid": false + }, + { + "description": "zero cannot be followed by other digits, plus octothorpe", + "data": "01#", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/time.json python-jsonschema-4.6.0/json/tests/latest/optional/format/time.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/time.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/time.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,180 @@ [ { "description": "validation of time strings", - "schema": {"format": "time"}, + "schema": { "format": "time" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid time string", + "data": "08:30:06Z", + "valid": true + }, + { + "description": "a valid time string with leap second, Zulu", + "data": "23:59:60Z", + "valid": true + }, + { + "description": "invalid leap second, Zulu (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "invalid leap second, Zulu (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "valid leap second, zero time-offset", + "data": "23:59:60+00:00", + "valid": true + }, + { + "description": "invalid leap second, zero time-offset (wrong hour)", + "data": "22:59:60+00:00", + "valid": false + }, + { + "description": "invalid leap second, zero time-offset (wrong minute)", + "data": "23:58:60+00:00", + "valid": false + }, + { + "description": "valid leap second, positive time-offset", + "data": "01:29:60+01:30", + "valid": true + }, + { + "description": "valid leap second, large positive time-offset", + "data": "23:29:60+23:30", + "valid": true + }, + { + "description": "invalid leap second, positive time-offset (wrong hour)", + "data": "23:59:60+01:00", + "valid": false + }, + { + "description": "invalid leap second, positive time-offset (wrong minute)", + "data": "23:59:60+00:30", + "valid": false + }, + { + "description": "valid leap second, negative time-offset", + "data": "15:59:60-08:00", + "valid": true + }, + { + "description": "valid leap second, large negative time-offset", + "data": "00:29:60-23:30", + "valid": true + }, + { + "description": "invalid leap second, negative time-offset (wrong hour)", + "data": "23:59:60-01:00", + "valid": false + }, + { + "description": "invalid leap second, negative time-offset (wrong minute)", + "data": "23:59:60-00:30", + "valid": false + }, + { + "description": "a valid time string with second fraction", + "data": "23:20:50.52Z", + "valid": true + }, + { + "description": "a valid time string with precise second fraction", "data": "08:30:06.283185Z", "valid": true }, { - "description": "an invalid time string", + "description": "a valid time string with plus offset", + "data": "08:30:06+00:20", + "valid": true + }, + { + "description": "a valid time string with minus offset", + "data": "08:30:06-08:00", + "valid": true + }, + { + "description": "a valid time string with case-insensitive Z", + "data": "08:30:06z", + "valid": true + }, + { + "description": "an invalid time string with invalid hour", + "data": "24:00:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid minute", + "data": "00:60:00Z", + "valid": false + }, + { + "description": "an invalid time string with invalid second", + "data": "00:00:61Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong hour)", + "data": "22:59:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid leap second (wrong minute)", + "data": "23:58:60Z", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset hour", + "data": "01:02:03+24:00", + "valid": false + }, + { + "description": "an invalid time string with invalid time numoffset minute", + "data": "01:02:03+00:60", + "valid": false + }, + { + "description": "an invalid time string with invalid time with both Z and numoffset", + "data": "01:02:03Z+00:30", + "valid": false + }, + { + "description": "an invalid offset indicator", "data": "08:30:06 PST", "valid": false }, @@ -17,6 +182,16 @@ "description": "only RFC3339 not all of ISO 8601 are valid", "data": "01:01:01,1111", "valid": false + }, + { + "description": "no time offset", + "data": "12:00:00", + "valid": false + }, + { + "description": "non-ascii digits should be rejected", + "data": "1২:00:00Z", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/unknown.json python-jsonschema-4.6.0/json/tests/latest/optional/format/unknown.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/unknown.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/unknown.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,43 @@ +[ + { + "description": "unknown format", + "schema": { "format": "unknown" }, + "tests": [ + { + "description": "unknown formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "unknown formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "unknown formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "unknown formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "unknown formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "unknown formats ignore nulls", + "data": null, + "valid": true + }, + { + "description": "unknown formats ignore strings", + "data": "string", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/uri.json python-jsonschema-4.6.0/json/tests/latest/optional/format/uri.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/uri.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/uri.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,7 +1,7 @@ [ { "description": "validation of URIs", - "schema": {"format": "uri"}, + "schema": { "format": "uri" }, "tests": [ { "description": "a valid URL with anchor tag", @@ -9,7 +9,7 @@ "valid": true }, { - "description": "a valid URL with anchor tag and parantheses", + "description": "a valid URL with anchor tag and parentheses", "data": "http://foo.com/blah_(wikipedia)_blah#cite-1", "valid": true }, @@ -97,6 +97,11 @@ "description": "an invalid URI with spaces and missing scheme", "data": ":// should fail", "valid": false + }, + { + "description": "an invalid URI with comma in scheme", + "data": "bar,baz:foo", + "valid": false } ] } diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/uri-reference.json python-jsonschema-4.6.0/json/tests/latest/optional/format/uri-reference.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/uri-reference.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/uri-reference.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "validation of URI References", - "schema": {"format": "uri-reference"}, + "schema": { "format": "uri-reference" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid URI", "data": "http://foo.bar/?baz=qux#quux", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/uri-template.json python-jsonschema-4.6.0/json/tests/latest/optional/format/uri-template.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/uri-template.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/uri-template.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,39 @@ [ { "description": "format: uri-template", - "schema": {"format": "uri-template"}, + "schema": { "format": "uri-template" }, "tests": [ { + "description": "all string formats ignore integers", + "data": 12, + "valid": true + }, + { + "description": "all string formats ignore floats", + "data": 13.7, + "valid": true + }, + { + "description": "all string formats ignore objects", + "data": {}, + "valid": true + }, + { + "description": "all string formats ignore arrays", + "data": [], + "valid": true + }, + { + "description": "all string formats ignore booleans", + "data": false, + "valid": true + }, + { + "description": "all string formats ignore nulls", + "data": null, + "valid": true + }, + { "description": "a valid uri-template", "data": "http://example.com/dictionary/{term:1}/{term}", "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format/uuid.json python-jsonschema-4.6.0/json/tests/latest/optional/format/uuid.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format/uuid.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format/uuid.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,85 @@ +[ + { + "description": "uuid format", + "schema": { + "format": "uuid" + }, + "tests": [ + { + "description": "all upper-case", + "data": "2EB8AA08-AA98-11EA-B4AA-73B441D16380", + "valid": true + }, + { + "description": "all lower-case", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d16380", + "valid": true + }, + { + "description": "mixed case", + "data": "2eb8aa08-AA98-11ea-B4Aa-73B441D16380", + "valid": true + }, + { + "description": "all zeroes is valid", + "data": "00000000-0000-0000-0000-000000000000", + "valid": true + }, + { + "description": "wrong length", + "data": "2eb8aa08-aa98-11ea-b4aa-73b441d1638", + "valid": false + }, + { + "description": "missing section", + "data": "2eb8aa08-aa98-11ea-73b441d16380", + "valid": false + }, + { + "description": "bad characters (not hex)", + "data": "2eb8aa08-aa98-11ea-b4ga-73b441d16380", + "valid": false + }, + { + "description": "no dashes", + "data": "2eb8aa08aa9811eab4aa73b441d16380", + "valid": false + }, + { + "description": "too few dashes", + "data": "2eb8aa08aa98-11ea-b4aa73b441d16380", + "valid": false + }, + { + "description": "too many dashes", + "data": "2eb8-aa08-aa98-11ea-b4aa73b44-1d16380", + "valid": false + }, + { + "description": "dashes in the wrong spot", + "data": "2eb8aa08aa9811eab4aa73b441d16380----", + "valid": false + }, + { + "description": "valid version 4", + "data": "98d80576-482e-427f-8434-7f86890ab222", + "valid": true + }, + { + "description": "valid version 5", + "data": "99c17cbb-656f-564a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 6", + "data": "99c17cbb-656f-664a-940f-1a4568f03487", + "valid": true + }, + { + "description": "hypothetical version 15", + "data": "99c17cbb-656f-f64a-940f-1a4568f03487", + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/format-assertion.json python-jsonschema-4.6.0/json/tests/latest/optional/format-assertion.json --- python-jsonschema-3.2.0/json/tests/latest/optional/format-assertion.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/format-assertion.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,42 @@ +[ + { + "description": "schema that uses custom metaschema with format-assertion: false", + "schema": { + "$id": "https://schema/using/format-assertion/false", + "$schema": "http://localhost:1234/draft2020-12/format-assertion-false.json", + "format": "ipv4" + }, + "tests": [ + { + "description": "format-assertion: false: valid string", + "data": "127.0.0.1", + "valid": true + }, + { + "description": "format-assertion: false: invalid string", + "data": "not-an-ipv4", + "valid": false + } + ] + }, + { + "description": "schema that uses custom metaschema with format-assertion: true", + "schema": { + "$id": "https://schema/using/format-assertion/true", + "$schema": "http://localhost:1234/draft2020-12/format-assertion-true.json", + "format": "ipv4" + }, + "tests": [ + { + "description": "format-assertion: true: valid string", + "data": "127.0.0.1", + "valid": true + }, + { + "description": "format-assertion: true: invalid string", + "data": "not-an-ipv4", + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/non-bmp-regex.json python-jsonschema-4.6.0/json/tests/latest/optional/non-bmp-regex.json --- python-jsonschema-3.2.0/json/tests/latest/optional/non-bmp-regex.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/non-bmp-regex.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,82 @@ +[ + { + "description": "Proper UTF-16 surrogate pair handling: pattern", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { "pattern": "^🐲*$" }, + "tests": [ + { + "description": "matches empty", + "data": "", + "valid": true + }, + { + "description": "matches single", + "data": "🐲", + "valid": true + }, + { + "description": "matches two", + "data": "🐲🐲", + "valid": true + }, + { + "description": "doesn't match one", + "data": "🐉", + "valid": false + }, + { + "description": "doesn't match two", + "data": "🐉🐉", + "valid": false + }, + { + "description": "doesn't match one ASCII", + "data": "D", + "valid": false + }, + { + "description": "doesn't match two ASCII", + "data": "DD", + "valid": false + } + ] + }, + { + "description": "Proper UTF-16 surrogate pair handling: patternProperties", + "comment": "Optional because .Net doesn't correctly handle 32-bit Unicode characters", + "schema": { + "patternProperties": { + "^🐲*$": { + "type": "integer" + } + } + }, + "tests": [ + { + "description": "matches empty", + "data": { "": 1 }, + "valid": true + }, + { + "description": "matches single", + "data": { "🐲": 1 }, + "valid": true + }, + { + "description": "matches two", + "data": { "🐲🐲": 1 }, + "valid": true + }, + { + "description": "doesn't match one", + "data": { "🐲": "hello" }, + "valid": false + }, + { + "description": "doesn't match two", + "data": { "🐲🐲": "hello" }, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/refOfUnknownKeyword.json python-jsonschema-4.6.0/json/tests/latest/optional/refOfUnknownKeyword.json --- python-jsonschema-3.2.0/json/tests/latest/optional/refOfUnknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/refOfUnknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,44 @@ +[ + { + "description": "reference of a root arbitrary keyword ", + "schema": { + "unknown-keyword": {"type": "integer"}, + "properties": { + "bar": {"$ref": "#/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "reference of an arbitrary keyword of a sub-schema", + "schema": { + "properties": { + "foo": {"unknown-keyword": {"type": "integer"}}, + "bar": {"$ref": "#/properties/foo/unknown-keyword"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/optional/zeroTerminatedFloats.json python-jsonschema-4.6.0/json/tests/latest/optional/zeroTerminatedFloats.json --- python-jsonschema-3.2.0/json/tests/latest/optional/zeroTerminatedFloats.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/optional/zeroTerminatedFloats.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -[ - { - "description": "some languages do not distinguish between different types of numeric value", - "schema": { - "type": "integer" - }, - "tests": [ - { - "description": "a float without fractional part is an integer", - "data": 1.0, - "valid": true - } - ] - } -] diff -Nru python-jsonschema-3.2.0/json/tests/latest/pattern.json python-jsonschema-4.6.0/json/tests/latest/pattern.json --- python-jsonschema-3.2.0/json/tests/latest/pattern.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/pattern.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,9 +14,34 @@ "valid": false }, { - "description": "ignores non-strings", + "description": "ignores booleans", "data": true, "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true } ] }, diff -Nru python-jsonschema-3.2.0/json/tests/latest/patternProperties.json python-jsonschema-4.6.0/json/tests/latest/patternProperties.json --- python-jsonschema-3.2.0/json/tests/latest/patternProperties.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/patternProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -142,6 +142,11 @@ "valid": false }, { + "description": "object with a property matching both true and false is invalid", + "data": {"foobar":1}, + "valid": false + }, + { "description": "empty object is valid", "data": {}, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/prefixItems.json python-jsonschema-4.6.0/json/tests/latest/prefixItems.json --- python-jsonschema-3.2.0/json/tests/latest/prefixItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/prefixItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,81 @@ +[ + { + "description": "a schema given for prefixItems", + "schema": { + "prefixItems": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + }, + { + "description": "incomplete array of items", + "data": [ 1 ], + "valid": true + }, + { + "description": "array with additional items", + "data": [ 1, "foo", true ], + "valid": true + }, + { + "description": "empty array", + "data": [ ], + "valid": true + }, + { + "description": "JavaScript pseudo-array is valid", + "data": { + "0": "invalid", + "1": "valid", + "length": 2 + }, + "valid": true + } + ] + }, + { + "description": "prefixItems with boolean schemas", + "schema": { + "prefixItems": [true, false] + }, + "tests": [ + { + "description": "array with one item is valid", + "data": [ 1 ], + "valid": true + }, + { + "description": "array with two items is invalid", + "data": [ 1, "foo" ], + "valid": false + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "additional items are allowed by default", + "schema": {"prefixItems": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/ref.json python-jsonschema-4.6.0/json/tests/latest/ref.json --- python-jsonschema-3.2.0/json/tests/latest/ref.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/ref.json 2022-06-01 20:26:26.000000000 +0000 @@ -54,9 +54,9 @@ { "description": "relative pointer ref to array", "schema": { - "items": [ + "prefixItems": [ {"type": "integer"}, - {"$ref": "#/items/0"} + {"$ref": "#/prefixItems/0"} ] }, "tests": [ @@ -75,13 +75,15 @@ { "description": "escaped pointer ref", "schema": { - "tilda~field": {"type": "integer"}, - "slash/field": {"type": "integer"}, - "percent%field": {"type": "integer"}, + "$defs": { + "tilde~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"} + }, "properties": { - "tilda": {"$ref": "#/tilda~0field"}, - "slash": {"$ref": "#/slash~1field"}, - "percent": {"$ref": "#/percent%25field"} + "tilde": {"$ref": "#/$defs/tilde~0field"}, + "slash": {"$ref": "#/$defs/slash~1field"}, + "percent": {"$ref": "#/$defs/percent%25field"} } }, "tests": [ @@ -91,8 +93,8 @@ "valid": false }, { - "description": "tilda invalid", - "data": {"tilda": "aoeu"}, + "description": "tilde invalid", + "data": {"tilde": "aoeu"}, "valid": false }, { @@ -106,8 +108,8 @@ "valid": true }, { - "description": "tilda valid", - "data": {"tilda": 123}, + "description": "tilde valid", + "data": {"tilde": 123}, "valid": true }, { @@ -141,7 +143,7 @@ ] }, { - "description": "ref overrides any sibling keywords", + "description": "ref applies alongside sibling keywords", "schema": { "$defs": { "reffed": { @@ -157,14 +159,14 @@ }, "tests": [ { - "description": "ref valid", + "description": "ref valid, maxItems valid", "data": { "foo": [] }, "valid": true }, { - "description": "ref valid, maxItems ignored", - "data": { "foo": [ 1, 2, 3] }, - "valid": true + "description": "ref valid, maxItems invalid", + "data": { "foo": [1, 2, 3] }, + "valid": false }, { "description": "ref invalid", @@ -175,7 +177,9 @@ }, { "description": "remote ref, containing refs itself", - "schema": {"$ref": "https://json-schema.org/draft/2019-09/schema"}, + "schema": { + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, "tests": [ { "description": "remote ref valid", @@ -210,6 +214,31 @@ ] }, { + "description": "property named $ref, containing an actual $ref", + "schema": { + "properties": { + "$ref": {"$ref": "#/$defs/is-string"} + }, + "$defs": { + "is-string": { + "type": "string" + } + } + }, + "tests": [ + { + "description": "property named $ref valid", + "data": {"$ref": "a"}, + "valid": true + }, + { + "description": "property named $ref invalid", + "data": {"$ref": 2}, + "valid": false + } + ] + }, + { "description": "$ref to boolean schema true", "schema": { "$ref": "#/$defs/bool", @@ -271,7 +300,7 @@ "tests": [ { "description": "valid tree", - "data": { + "data": { "meta": "root", "nodes": [ { @@ -300,7 +329,7 @@ }, { "description": "invalid tree", - "data": { + "data": { "meta": "root", "nodes": [ { @@ -355,5 +384,198 @@ "valid": false } ] + }, + { + "description": "ref creates new scope when adjacent to keywords", + "schema": { + "$defs": { + "A": { + "unevaluatedProperties": false + } + }, + "properties": { + "prop1": { + "type": "string" + } + }, + "$ref": "#/$defs/A" + }, + "tests": [ + { + "description": "referenced subschema doesn't see annotations from properties", + "data": { + "prop1": "match" + }, + "valid": false + } + ] + }, + { + "description": "naive replacement of $ref with its destination is not correct", + "schema": { + "$defs": { + "a_string": { "type": "string" } + }, + "enum": [ + { "$ref": "#/$defs/a_string" } + ] + }, + "tests": [ + { + "description": "do not evaluate the $ref inside the enum, matching any string", + "data": "this is a string", + "valid": false + }, + { + "description": "do not evaluate the $ref inside the enum, definition exact match", + "data": { "type": "string" }, + "valid": false + }, + { + "description": "match the enum exactly", + "data": { "$ref": "#/$defs/a_string" }, + "valid": true + } + ] + }, + { + "description": "refs with relative uris and defs", + "schema": { + "$id": "http://example.com/schema-relative-uri-defs1.json", + "properties": { + "foo": { + "$id": "schema-relative-uri-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-relative-uri-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "relative refs with absolute uris and defs", + "schema": { + "$id": "http://example.com/schema-refs-absolute-uris-defs1.json", + "properties": { + "foo": { + "$id": "http://example.com/schema-refs-absolute-uris-defs2.json", + "$defs": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "$ref": "#/$defs/inner" + } + }, + "$ref": "schema-refs-absolute-uris-defs2.json" + }, + "tests": [ + { + "description": "invalid on inner field", + "data": { + "foo": { + "bar": 1 + }, + "bar": "a" + }, + "valid": false + }, + { + "description": "invalid on outer field", + "data": { + "foo": { + "bar": "a" + }, + "bar": 1 + }, + "valid": false + }, + { + "description": "valid on both fields", + "data": { + "foo": { + "bar": "a" + }, + "bar": "a" + }, + "valid": true + } + ] + }, + { + "description": "$id must be resolved against nearest parent, not just immediate parent", + "schema": { + "$id": "http://example.com/a.json", + "$defs": { + "x": { + "$id": "http://example.com/b/c.json", + "not": { + "$defs": { + "y": { + "$id": "d.json", + "type": "number" + } + } + } + } + }, + "allOf": [ + { + "$ref": "http://example.com/b/d.json" + } + ] + }, + "tests": [ + { + "description": "number should pass", + "data": 1, + "valid": true + }, + { + "description": "non-number should fail", + "data": "a", + "valid": false + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/refRemote.json python-jsonschema-4.6.0/json/tests/latest/refRemote.json --- python-jsonschema-3.2.0/json/tests/latest/refRemote.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/refRemote.json 2022-06-01 20:26:26.000000000 +0000 @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "schema": {"$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + "$ref": "http://localhost:1234/subSchemas-defs.json#/$defs/refToInteger" }, "tests": [ { @@ -54,7 +54,7 @@ "schema": { "$id": "http://localhost:1234/", "items": { - "$id": "folder/", + "$id": "baseUriChange/", "items": {"$ref": "folderInteger.json"} } }, @@ -76,10 +76,10 @@ "schema": { "$id": "http://localhost:1234/scope_change_defs1.json", "type" : "object", - "properties": {"list": {"$ref": "#/$defs/baz"}}, + "properties": {"list": {"$ref": "baseUriChangeFolder/"}}, "$defs": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolder/", "type": "array", "items": {"$ref": "folderInteger.json"} } @@ -103,10 +103,10 @@ "schema": { "$id": "http://localhost:1234/scope_change_defs2.json", "type" : "object", - "properties": {"list": {"$ref": "#/$defs/baz/$defs/bar"}}, + "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}}, "$defs": { "baz": { - "$id": "folder/", + "$id": "baseUriChangeFolderInSubschema/", "$defs": { "bar": { "type": "array", @@ -163,5 +163,28 @@ "valid": false } ] + }, + { + "description": "remote ref with ref to defs", + "schema": { + "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", + "$ref": "ref-and-defs.json" + }, + "tests": [ + { + "description": "invalid", + "data": { + "bar": 1 + }, + "valid": false + }, + { + "description": "valid", + "data": { + "bar": "a" + }, + "valid": true + } + ] } ] diff -Nru python-jsonschema-3.2.0/json/tests/latest/type.json python-jsonschema-4.6.0/json/tests/latest/type.json --- python-jsonschema-3.2.0/json/tests/latest/type.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/type.json 2022-06-01 20:26:26.000000000 +0000 @@ -9,6 +9,11 @@ "valid": true }, { + "description": "a float with zero fractional part is an integer", + "data": 1.0, + "valid": true + }, + { "description": "a float is not an integer", "data": 1.1, "valid": false @@ -55,6 +60,11 @@ "valid": true }, { + "description": "a float with zero fractional part is a number (and an integer)", + "data": 1.0, + "valid": true + }, + { "description": "a float is a number", "data": 1.1, "valid": true diff -Nru python-jsonschema-3.2.0/json/tests/latest/unevaluatedItems.json python-jsonschema-4.6.0/json/tests/latest/unevaluatedItems.json --- python-jsonschema-3.2.0/json/tests/latest/unevaluatedItems.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/unevaluatedItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,633 @@ +[ + { + "description": "unevaluatedItems true", + "schema": { + "type": "array", + "unevaluatedItems": true + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems false", + "schema": { + "type": "array", + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems as schema", + "schema": { + "type": "array", + "unevaluatedItems": { "type": "string" } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with valid unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with invalid unevaluated items", + "data": [42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with uniform items", + "schema": { + "type": "array", + "items": { "type": "string" }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", "bar"], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with tuple", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with items", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "items": true, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "unevaluatedItems doesn't apply", + "data": ["foo", 42], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested tuple", + "schema": { + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "allOf": [ + { + "prefixItems": [ + true, + { "type": "number" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", 42], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", 42, true], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with nested items", + "schema": { + "type": "array", + "allOf": [ + { + "prefixItems": [ + { "type": "string" } + ], + "items": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with nested unevaluatedItems", + "schema": { + "type": "array", + "allOf": [ + { + "prefixItems": [ + { "type": "string" } + ] + }, + { + "unevaluatedItems": true + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no additional items", + "data": ["foo"], + "valid": true + }, + { + "description": "with additional items", + "data": ["foo", 42, true], + "valid": true + } + ] + }, + { + "description": "unevaluatedItems with anyOf", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "anyOf": [ + { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + { + "prefixItems": [ + true, + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when one schema matches and has no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "when one schema matches and has unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + }, + { + "description": "when two schemas match and has no unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "when two schemas match and has unevaluated items", + "data": ["foo", "bar", "baz", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with oneOf", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "oneOf": [ + { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + { + "prefixItems": [ + true, + { "const": "baz" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with not", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "not": { + "not": { + "prefixItems": [ + true, + { "const": "bar" } + ] + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with unevaluated items", + "data": ["foo", "bar"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with if/then/else", + "schema": { + "type": "array", + "prefixItems": [ + { "const": "foo" } + ], + "if": { + "prefixItems": [ + true, + { "const": "bar" } + ] + }, + "then": { + "prefixItems": [ + true, + true, + { "const": "then" } + ] + }, + "else": { + "prefixItems": [ + true, + true, + true, + { "const": "else" } + ] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "when if matches and it has no unevaluated items", + "data": ["foo", "bar", "then"], + "valid": true + }, + { + "description": "when if matches and it has unevaluated items", + "data": ["foo", "bar", "then", "else"], + "valid": false + }, + { + "description": "when if doesn't match and it has no unevaluated items", + "data": ["foo", 42, 42, "else"], + "valid": true + }, + { + "description": "when if doesn't match and it has unevaluated items", + "data": ["foo", 42, 42, "else", 42], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with boolean schemas", + "schema": { + "type": "array", + "allOf": [true], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $ref", + "schema": { + "type": "array", + "$ref": "#/$defs/bar", + "prefixItems": [ + { "type": "string" } + ], + "unevaluatedItems": false, + "$defs": { + "bar": { + "prefixItems": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems can't see inside cousins", + "schema": { + "allOf": [ + { + "prefixItems": [ true ] + }, + { + "unevaluatedItems": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": [ 1 ], + "valid": false + } + ] + }, + { + "description": "item is evaluated in an uncle schema to unevaluatedItems", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "prefixItems": [ + { + "type": "string" + } + ], + "unevaluatedItems": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "prefixItems": [ + true, + { + "type": "string" + } + ] + } + } + } + ] + }, + "tests": [ + { + "description": "no extra items", + "data": { + "foo": [ + "test" + ] + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": [ + "test", + "test" + ] + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedItems depends on adjacent contains", + "schema": { + "prefixItems": [true], + "contains": {"type": "string"}, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "second item is evaluated by contains", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "contains fails, second item is not evaluated", + "data": [ 1, 2 ], + "valid": false + }, + { + "description": "contains passes, second item is not evaluated", + "data": [ 1, 2, "foo" ], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems depends on multiple nested contains", + "schema": { + "allOf": [ + { "contains": { "multipleOf": 2 } }, + { "contains": { "multipleOf": 3 } } + ], + "unevaluatedItems": { "multipleOf": 5 } + }, + "tests": [ + { + "description": "5 not evaluated, passes unevaluatedItems", + "data": [ 2, 3, 4, 5, 6 ], + "valid": true + }, + { + "description": "7 not evaluated, fails unevaluatedItems", + "data": [ 2, 3, 4, 7, 8 ], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems and contains interact to control item dependency relationship", + "schema": { + "if": { + "contains": {"const": "a"} + }, + "then": { + "if": { + "contains": {"const": "b"} + }, + "then": { + "if": { + "contains": {"const": "c"} + } + } + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "empty array is valid", + "data": [], + "valid": true + }, + { + "description": "only a's are valid", + "data": [ "a", "a" ], + "valid": true + }, + { + "description": "a's and b's are valid", + "data": [ "a", "b", "a", "b", "a" ], + "valid": true + }, + { + "description": "a's, b's and c's are valid", + "data": [ "c", "a", "c", "c", "b", "a" ], + "valid": true + }, + { + "description": "only b's are invalid", + "data": [ "b", "b" ], + "valid": false + }, + { + "description": "only c's are invalid", + "data": [ "c", "c" ], + "valid": false + }, + { + "description": "only b's and c's are invalid", + "data": [ "c", "b", "c", "b", "c" ], + "valid": false + }, + { + "description": "only a's and c's are invalid", + "data": [ "c", "a", "c", "a", "c" ], + "valid": false + } + ] + }, + { + "description": "non-array instances are valid", + "schema": {"unevaluatedItems": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores objects", + "data": {}, + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/unevaluatedProperties.json python-jsonschema-4.6.0/json/tests/latest/unevaluatedProperties.json --- python-jsonschema-3.2.0/json/tests/latest/unevaluatedProperties.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/unevaluatedProperties.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,1347 @@ +[ + { + "description": "unevaluatedProperties true", + "schema": { + "type": "object", + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties schema", + "schema": { + "type": "object", + "unevaluatedProperties": { + "type": "string", + "minLength": 3 + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with valid unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with invalid unevaluated properties", + "data": { + "foo": "fo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties false", + "schema": { + "type": "object", + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": {}, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent patternProperties", + "schema": { + "type": "object", + "patternProperties": { + "^foo": { "type": "string" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with adjacent additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "additionalProperties": true, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested properties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "properties": { + "bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested patternProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "patternProperties": { + "^bar": { "type": "string" } + } + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with nested additionalProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "additionalProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with additional properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with nested unevaluatedProperties", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": { + "type": "string", + "maxLength": 2 + } + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties with anyOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "anyOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + }, + { + "properties": { + "quux": { "const": "quux" } + }, + "required": ["quux"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when one matches and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when one matches and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "not-baz" + }, + "valid": false + }, + { + "description": "when two match and has no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": true + }, + { + "description": "when two match and has unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz", + "quux": "not-quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with oneOf", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "oneOf": [ + { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + }, + { + "properties": { + "baz": { "const": "baz" } + }, + "required": ["baz"] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "quux": "quux" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with not", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "not": { + "not": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, then not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "else": { + "properties": { + "baz": { "type": "string" } + }, + "required": ["baz"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": false + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": true + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with if/then/else, else not defined", + "schema": { + "type": "object", + "if": { + "properties": { + "foo": { "const": "then" } + }, + "required": ["foo"] + }, + "then": { + "properties": { + "bar": { "type": "string" } + }, + "required": ["bar"] + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "when if is true and has no unevaluated properties", + "data": { + "foo": "then", + "bar": "bar" + }, + "valid": true + }, + { + "description": "when if is true and has unevaluated properties", + "data": { + "foo": "then", + "bar": "bar", + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has no unevaluated properties", + "data": { + "baz": "baz" + }, + "valid": false + }, + { + "description": "when if is false and has unevaluated properties", + "data": { + "foo": "else", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with dependentSchemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "dependentSchemas": { + "foo": { + "properties": { + "bar": { "const": "bar" } + }, + "required": ["bar"] + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with boolean schemas", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [true], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $ref", + "schema": { + "type": "object", + "$ref": "#/$defs/bar", + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false, + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties can't see inside cousins", + "schema": { + "allOf": [ + { + "properties": { + "foo": true + } + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "always fails", + "data": { + "foo": 1 + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer false, inner true, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties outside", + "schema": { + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "allOf": [ + { + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "nested unevaluatedProperties, outer true, inner false, properties inside", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ], + "unevaluatedProperties": true + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, true with properties", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": true + }, + { + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": false + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "cousin unevaluatedProperties, true and false, false with properties", + "schema": { + "type": "object", + "allOf": [ + { + "unevaluatedProperties": true + }, + { + "properties": { + "foo": { "type": "string" } + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "with no nested unevaluated properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with nested unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": false + } + ] + }, + { + "description": "property is evaluated in an uncle schema to unevaluatedProperties", + "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", + "schema": { + "type": "object", + "properties": { + "foo": { + "type": "object", + "properties": { + "bar": { + "type": "string" + } + }, + "unevaluatedProperties": false + } + }, + "anyOf": [ + { + "properties": { + "foo": { + "properties": { + "faz": { + "type": "string" + } + } + } + } + } + ] + }, + "tests": [ + { + "description": "no extra properties", + "data": { + "foo": { + "bar": "test" + } + }, + "valid": true + }, + { + "description": "uncle keyword evaluation is not significant", + "data": { + "foo": { + "bar": "test", + "faz": "test" + } + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, allOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + }, + "unevaluatedProperties": false + } + ], + "anyOf": [ + { + "properties": { + "bar": true + } + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": true + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": false + } + ] + }, + { + "description": "in-place applicator siblings, anyOf has unevaluated", + "schema": { + "type": "object", + "allOf": [ + { + "properties": { + "foo": true + } + } + ], + "anyOf": [ + { + "properties": { + "bar": true + }, + "unevaluatedProperties": false + } + ] + }, + "tests": [ + { + "description": "base case: both properties present", + "data": { + "foo": 1, + "bar": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, bar is missing", + "data": { + "foo": 1 + }, + "valid": false + }, + { + "description": "in place applicator siblings, foo is missing", + "data": { + "bar": 1 + }, + "valid": true + } + ] + }, + { + "description": "unevaluatedProperties + single cyclic ref", + "schema": { + "type": "object", + "properties": { + "x": { "$ref": "#" } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is valid", + "data": {}, + "valid": true + }, + { + "description": "Single is valid", + "data": { "x": {} }, + "valid": true + }, + { + "description": "Unevaluated on 1st level is invalid", + "data": { "x": {}, "y": {} }, + "valid": false + }, + { + "description": "Nested is valid", + "data": { "x": { "x": {} } }, + "valid": true + }, + { + "description": "Unevaluated on 2nd level is invalid", + "data": { "x": { "x": {}, "y": {} } }, + "valid": false + }, + { + "description": "Deep nested is valid", + "data": { "x": { "x": { "x": {} } } }, + "valid": true + }, + { + "description": "Unevaluated on 3rd level is invalid", + "data": { "x": { "x": { "x": {}, "y": {} } } }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties + ref inside allOf / oneOf", + "schema": { + "$defs": { + "one": { + "properties": { "a": true } + }, + "two": { + "required": ["x"], + "properties": { "x": true } + } + }, + "allOf": [ + { "$ref": "#/$defs/one" }, + { "properties": { "b": true } }, + { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { + "required": ["y"], + "properties": { "y": true } + } + ] + } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid (no x or y)", + "data": {}, + "valid": false + }, + { + "description": "a and b are invalid (no x or y)", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "x and y are invalid", + "data": { "x": 1, "y": 1 }, + "valid": false + }, + { + "description": "a and x are valid", + "data": { "a": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and y are valid", + "data": { "a": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x are valid", + "data": { "a": 1, "b": 1, "x": 1 }, + "valid": true + }, + { + "description": "a and b and y are valid", + "data": { "a": 1, "b": 1, "y": 1 }, + "valid": true + }, + { + "description": "a and b and x and y are invalid", + "data": { "a": 1, "b": 1, "x": 1, "y": 1 }, + "valid": false + } + ] + }, + { + "description": "dynamic evalation inside nested refs", + "schema": { + "$defs": { + "one": { + "oneOf": [ + { "$ref": "#/$defs/two" }, + { "required": ["b"], "properties": { "b": true } }, + { "required": ["xx"], "patternProperties": { "x": true } }, + { "required": ["all"], "unevaluatedProperties": true } + ] + }, + "two": { + "oneOf": [ + { "required": ["c"], "properties": { "c": true } }, + { "required": ["d"], "properties": { "d": true } } + ] + } + }, + "oneOf": [ + { "$ref": "#/$defs/one" }, + { "required": ["a"], "properties": { "a": true } } + ], + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "Empty is invalid", + "data": {}, + "valid": false + }, + { + "description": "a is valid", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "b is valid", + "data": { "b": 1 }, + "valid": true + }, + { + "description": "c is valid", + "data": { "c": 1 }, + "valid": true + }, + { + "description": "d is valid", + "data": { "d": 1 }, + "valid": true + }, + { + "description": "a + b is invalid", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "a + c is invalid", + "data": { "a": 1, "c": 1 }, + "valid": false + }, + { + "description": "a + d is invalid", + "data": { "a": 1, "d": 1 }, + "valid": false + }, + { + "description": "b + c is invalid", + "data": { "b": 1, "c": 1 }, + "valid": false + }, + { + "description": "b + d is invalid", + "data": { "b": 1, "d": 1 }, + "valid": false + }, + { + "description": "c + d is invalid", + "data": { "c": 1, "d": 1 }, + "valid": false + }, + { + "description": "xx is valid", + "data": { "xx": 1 }, + "valid": true + }, + { + "description": "xx + foox is valid", + "data": { "xx": 1, "foox": 1 }, + "valid": true + }, + { + "description": "xx + foo is invalid", + "data": { "xx": 1, "foo": 1 }, + "valid": false + }, + { + "description": "xx + a is invalid", + "data": { "xx": 1, "a": 1 }, + "valid": false + }, + { + "description": "xx + b is invalid", + "data": { "xx": 1, "b": 1 }, + "valid": false + }, + { + "description": "xx + c is invalid", + "data": { "xx": 1, "c": 1 }, + "valid": false + }, + { + "description": "xx + d is invalid", + "data": { "xx": 1, "d": 1 }, + "valid": false + }, + { + "description": "all is valid", + "data": { "all": 1 }, + "valid": true + }, + { + "description": "all + foo is valid", + "data": { "all": 1, "foo": 1 }, + "valid": true + }, + { + "description": "all + a is invalid", + "data": { "all": 1, "a": 1 }, + "valid": false + } + ] + }, + { + "description": "non-object instances are valid", + "schema": {"unevaluatedProperties": false}, + "tests": [ + { + "description": "ignores booleans", + "data": true, + "valid": true + }, + { + "description": "ignores integers", + "data": 123, + "valid": true + }, + { + "description": "ignores floats", + "data": 1.0, + "valid": true + }, + { + "description": "ignores arrays", + "data": [], + "valid": true + }, + { + "description": "ignores strings", + "data": "foo", + "valid": true + }, + { + "description": "ignores null", + "data": null, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/uniqueItems.json python-jsonschema-4.6.0/json/tests/latest/uniqueItems.json --- python-jsonschema-3.2.0/json/tests/latest/uniqueItems.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/uniqueItems.json 2022-06-01 20:26:26.000000000 +0000 @@ -14,6 +14,11 @@ "valid": false }, { + "description": "non-unique array of more than two integers is invalid", + "data": [1, 2, 1], + "valid": false + }, + { "description": "numbers are unique if mathematically unequal", "data": [1.0, 1.00, 1], "valid": false @@ -29,6 +34,16 @@ "valid": true }, { + "description": "unique array of strings is valid", + "data": ["foo", "bar", "baz"], + "valid": true + }, + { + "description": "non-unique array of strings is invalid", + "data": ["foo", "bar", "foo"], + "valid": false + }, + { "description": "unique array of objects is valid", "data": [{"foo": "bar"}, {"foo": "baz"}], "valid": true @@ -65,6 +80,11 @@ "valid": false }, { + "description": "non-unique array of more than two arrays is invalid", + "data": [["foo"], ["bar"], ["foo"]], + "valid": false + }, + { "description": "1 and true are unique", "data": [1, true], "valid": true @@ -75,21 +95,61 @@ "valid": true }, { + "description": "[1] and [true] are unique", + "data": [[1], [true]], + "valid": true + }, + { + "description": "[0] and [false] are unique", + "data": [[0], [false]], + "valid": true + }, + { + "description": "nested [1] and [true] are unique", + "data": [[[1], "foo"], [[true], "foo"]], + "valid": true + }, + { + "description": "nested [0] and [false] are unique", + "data": [[[0], "foo"], [[false], "foo"]], + "valid": true + }, + { "description": "unique heterogeneous types are valid", - "data": [{}, [1], true, null, 1], + "data": [{}, [1], true, null, 1, "{}"], "valid": true }, { "description": "non-unique heterogeneous types are invalid", "data": [{}, [1], true, null, {}, 1], "valid": false + }, + { + "description": "different objects are unique", + "data": [{"a": 1, "b": 2}, {"a": 2, "b": 1}], + "valid": true + }, + { + "description": "objects are non-unique despite key order", + "data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}], + "valid": false + }, + { + "description": "{\"a\": false} and {\"a\": 0} are unique", + "data": [{"a": false}, {"a": 0}], + "valid": true + }, + { + "description": "{\"a\": true} and {\"a\": 1} are unique", + "data": [{"a": true}, {"a": 1}], + "valid": true } ] }, { "description": "uniqueItems with an array of items", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], "uniqueItems": true }, "tests": [ @@ -138,9 +198,9 @@ { "description": "uniqueItems with an array of items and additionalItems=false", "schema": { - "items": [{"type": "boolean"}, {"type": "boolean"}], - "uniqueItems": true, - "additionalItems": false + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": true, + "items": false }, "tests": [ { @@ -165,6 +225,177 @@ }, { "description": "extra items are invalid even if unique", + "data": [false, true, null], + "valid": false + } + ] + }, + { + "description": "uniqueItems=false validation", + "schema": { "uniqueItems": false }, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is valid", + "data": [1, 1], + "valid": true + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": true + }, + { + "description": "false is not equal to zero", + "data": [0, false], + "valid": true + }, + { + "description": "true is not equal to one", + "data": [1, true], + "valid": true + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": true + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": true + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is valid", + "data": [["foo"], ["foo"]], + "valid": true + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are valid", + "data": [{}, [1], true, null, {}, 1], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "unique array extended from [false, true] is valid", + "data": [false, true, "foo", "bar"], + "valid": true + }, + { + "description": "unique array extended from [true, false] is valid", + "data": [true, false, "foo", "bar"], + "valid": true + }, + { + "description": "non-unique array extended from [false, true] is valid", + "data": [false, true, "foo", "foo"], + "valid": true + }, + { + "description": "non-unique array extended from [true, false] is valid", + "data": [true, false, "foo", "foo"], + "valid": true + } + ] + }, + { + "description": "uniqueItems=false with an array of items and additionalItems=false", + "schema": { + "prefixItems": [{"type": "boolean"}, {"type": "boolean"}], + "uniqueItems": false, + "items": false + }, + "tests": [ + { + "description": "[false, true] from items array is valid", + "data": [false, true], + "valid": true + }, + { + "description": "[true, false] from items array is valid", + "data": [true, false], + "valid": true + }, + { + "description": "[false, false] from items array is valid", + "data": [false, false], + "valid": true + }, + { + "description": "[true, true] from items array is valid", + "data": [true, true], + "valid": true + }, + { + "description": "extra items are invalid even if unique", "data": [false, true, null], "valid": false } diff -Nru python-jsonschema-3.2.0/json/tests/latest/unknownKeyword.json python-jsonschema-4.6.0/json/tests/latest/unknownKeyword.json --- python-jsonschema-3.2.0/json/tests/latest/unknownKeyword.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/unknownKeyword.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,56 @@ +[ + { + "description": "$id inside an unknown keyword is not a real identifier", + "comment": "the implementation must not be confused by an $id in locations we do not know how to parse", + "schema": { + "$defs": { + "id_in_unknown0": { + "not": { + "array_of_schemas": [ + { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "null" + } + ] + } + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "string" + }, + "id_in_unknown1": { + "not": { + "object_of_schemas": { + "foo": { + "$id": "https://localhost:1234/unknownKeyword/my_identifier.json", + "type": "integer" + } + } + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_unknown0" }, + { "$ref": "#/$defs/id_in_unknown1" }, + { "$ref": "https://localhost:1234/unknownKeyword/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "type matches second anyOf, which has a real schema in it", + "data": "a string", + "valid": true + }, + { + "description": "type matches non-schema in first anyOf", + "data": null, + "valid": false + }, + { + "description": "type matches non-schema in third anyOf", + "data": 1, + "valid": false + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/tests/latest/vocabulary.json python-jsonschema-4.6.0/json/tests/latest/vocabulary.json --- python-jsonschema-3.2.0/json/tests/latest/vocabulary.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/json/tests/latest/vocabulary.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,38 @@ +[ + { + "description": "schema that uses custom metaschema with with no validation vocabulary", + "schema": { + "$id": "https://schema/using/no/validation", + "$schema": "http://localhost:1234/draft2020-12/metaschema-no-validation.json", + "properties": { + "badProperty": false, + "numberProperty": { + "minimum": 10 + } + } + }, + "tests": [ + { + "description": "applicator vocabulary still works", + "data": { + "badProperty": "this property should not exist" + }, + "valid": false + }, + { + "description": "no validation: valid number", + "data": { + "numberProperty": 20 + }, + "valid": true + }, + { + "description": "no validation: invalid number, but it still validates", + "data": { + "numberProperty": 1 + }, + "valid": true + } + ] + } +] diff -Nru python-jsonschema-3.2.0/json/test-schema.json python-jsonschema-4.6.0/json/test-schema.json --- python-jsonschema-3.2.0/json/test-schema.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/test-schema.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,59 +1,91 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-06/schema#", + "description": "Schema for tests", + "type": "array", + "items": { + "type": "object", + "required": [ "description", "schema", "tests" ], + "properties": { + "id": { + "description": "Uniquely identifies a set of tests", + "type": "string", + "format": "uri" + }, + "description": { + "description": "The test set description", + "type": "string" + }, + "comment": { + "description": "Any additional comments about the test set", + "type": "string" + }, + "schema": { + "description": "This should be a valid schema. This should be a ref to a meta-schema if schema keywords need testing." + }, + "tests": { + "description": "A set of related tests all using the same schema", + "type": "array", + "items": { "$ref": "#/definitions/test" }, + "minItems": 1 + } + }, + "additionalProperties": false, + "minItems": 1 + }, "definitions": { "outputItem": { "type": "object", "properties": { - "valid": {"type": "boolean"}, - "keywordLocation": {"type": "string"}, + "valid": { "type": "boolean" }, + "keywordLocation": { "type": "string" }, "absoluteKeywordLocation": { "type": "string", "format": "uri" }, - "instanceLocation": {"type": "string"}, + "instanceLocation": { "type": "string" }, "annotations": { "type": "array", - "items": {"$ref": "#/definitions/outputItem"} + "items": { "$ref": "#/definitions/outputItem" } }, "errors": { "type": "array", - "items": {"$ref": "#/definitions/outputItem"} + "items": { "$ref": "#/definitions/outputItem" } } } - } - }, - "type": "array", - "items": { - "type": "object", - "required": ["description", "schema", "tests"], - "properties": { - "description": {"type": "string"}, - "schema": {}, - "tests": { - "type": "array", - "items": { + }, + "test": { + "description": "A single test", + "type": "object", + "required": [ "description", "data", "valid" ], + "properties": { + "id": { + "description": "Uniquely identifies a single test", + "type": "string", + "format": "uri" + }, + "description": { + "description": "The test description", + "type": "string" + }, + "comment": { + "description": "Any additional comments about the test", + "type": "string" + }, + "data": { + "description": "This is the instance to be validated against the schema in \"schema\"." + }, + "valid": { "type": "boolean" }, + "output": { "type": "object", - "required": ["description", "data", "valid"], + "required": [ "basic", "detailed", "verbose" ], "properties": { - "description": {"type": "string"}, - "data": {}, - "valid": {"type": "boolean"}, - "output": { - "type": "object", - "properties": { - "basic": {"$ref": "#/definitions/outputItem"}, - "detailed": {"$ref": "#/definitions/outputItem"}, - "verbose": {"$ref": "#/definitions/outputItem"} - }, - "required": ["basic", "detailed", "verbose"] - } - }, - "additionalProperties": false - }, - "minItems": 1 - } - }, - "additionalProperties": false, - "minItems": 1 + "basic": { "$ref": "#/definitions/outputItem" }, + "detailed": { "$ref": "#/definitions/outputItem" }, + "verbose": { "$ref": "#/definitions/outputItem" } + } + } + }, + "additionalProperties": false + } } } diff -Nru python-jsonschema-3.2.0/json/tox.ini python-jsonschema-4.6.0/json/tox.ini --- python-jsonschema-3.2.0/json/tox.ini 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/tox.ini 2022-06-01 20:26:26.000000000 +0000 @@ -5,5 +5,5 @@ [testenv:sanity] # used just for validating the structure of the test case files themselves -deps = jsonschema +deps = jsonschema==3.2.0 commands = {envpython} bin/jsonschema_suite check diff -Nru python-jsonschema-3.2.0/json/.travis.yml python-jsonschema-4.6.0/json/.travis.yml --- python-jsonschema-3.2.0/json/.travis.yml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/json/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -language: python -python: "3.7" -node_js: "9" -install: - - pip install tox -script: - - tox - - npm install && npm test || true diff -Nru python-jsonschema-3.2.0/jsonschema/benchmarks/issue232.py python-jsonschema-4.6.0/jsonschema/benchmarks/issue232.py --- python-jsonschema-3.2.0/jsonschema/benchmarks/issue232.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/benchmarks/issue232.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,19 +1,18 @@ -#!/usr/bin/env python """ A performance benchmark using the example from issue #232. -See https://github.com/Julian/jsonschema/pull/232. +See https://github.com/python-jsonschema/jsonschema/pull/232. """ -from twisted.python.filepath import FilePath +from pathlib import Path + from pyperf import Runner from pyrsistent import m from jsonschema.tests._suite import Version import jsonschema - issue232 = Version( - path=FilePath(__file__).sibling("issue232"), + path=Path(__file__).parent / "issue232", remotes=m(), name="issue232", ) diff -Nru python-jsonschema-3.2.0/jsonschema/benchmarks/json_schema_test_suite.py python-jsonschema-4.6.0/jsonschema/benchmarks/json_schema_test_suite.py --- python-jsonschema-3.2.0/jsonschema/benchmarks/json_schema_test_suite.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/benchmarks/json_schema_test_suite.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,4 +1,3 @@ -#!/usr/bin/env python """ A performance benchmark using the official test suite. @@ -9,6 +8,5 @@ from jsonschema.tests._suite import Suite - if __name__ == "__main__": Suite().benchmark(runner=Runner()) diff -Nru python-jsonschema-3.2.0/jsonschema/cli.py python-jsonschema-4.6.0/jsonschema/cli.py --- python-jsonschema-3.2.0/jsonschema/cli.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/cli.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,14 +1,133 @@ """ The ``jsonschema`` command line. """ -from __future__ import absolute_import + +from json import JSONDecodeError +from textwrap import dedent import argparse import json import sys +import traceback + +try: + from importlib import metadata +except ImportError: + import importlib_metadata as metadata # type: ignore + +import attr -from jsonschema import __version__ from jsonschema._reflect import namedAny -from jsonschema.validators import validator_for +from jsonschema.exceptions import SchemaError +from jsonschema.validators import RefResolver, validator_for + + +class _CannotLoadFile(Exception): + pass + + +@attr.s +class _Outputter(object): + + _formatter = attr.ib() + _stdout = attr.ib() + _stderr = attr.ib() + + @classmethod + def from_arguments(cls, arguments, stdout, stderr): + if arguments["output"] == "plain": + formatter = _PlainFormatter(arguments["error_format"]) + elif arguments["output"] == "pretty": + formatter = _PrettyFormatter() + return cls(formatter=formatter, stdout=stdout, stderr=stderr) + + def load(self, path): + try: + file = open(path) + except FileNotFoundError: + self.filenotfound_error(path=path, exc_info=sys.exc_info()) + raise _CannotLoadFile() + + with file: + try: + return json.load(file) + except JSONDecodeError: + self.parsing_error(path=path, exc_info=sys.exc_info()) + raise _CannotLoadFile() + + def filenotfound_error(self, **kwargs): + self._stderr.write(self._formatter.filenotfound_error(**kwargs)) + + def parsing_error(self, **kwargs): + self._stderr.write(self._formatter.parsing_error(**kwargs)) + + def validation_error(self, **kwargs): + self._stderr.write(self._formatter.validation_error(**kwargs)) + + def validation_success(self, **kwargs): + self._stdout.write(self._formatter.validation_success(**kwargs)) + + +@attr.s +class _PrettyFormatter(object): + + _ERROR_MSG = dedent( + """\ + ===[{type}]===({path})=== + + {body} + ----------------------------- + """, + ) + _SUCCESS_MSG = "===[SUCCESS]===({path})===\n" + + def filenotfound_error(self, path, exc_info): + return self._ERROR_MSG.format( + path=path, + type="FileNotFoundError", + body="{!r} does not exist.".format(path), + ) + + def parsing_error(self, path, exc_info): + exc_type, exc_value, exc_traceback = exc_info + exc_lines = "".join( + traceback.format_exception(exc_type, exc_value, exc_traceback), + ) + return self._ERROR_MSG.format( + path=path, + type=exc_type.__name__, + body=exc_lines, + ) + + def validation_error(self, instance_path, error): + return self._ERROR_MSG.format( + path=instance_path, + type=error.__class__.__name__, + body=error, + ) + + def validation_success(self, instance_path): + return self._SUCCESS_MSG.format(path=instance_path) + + +@attr.s +class _PlainFormatter(object): + + _error_format = attr.ib() + + def filenotfound_error(self, path, exc_info): + return "{!r} does not exist.\n".format(path) + + def parsing_error(self, path, exc_info): + return "Failed to parse {}: {}\n".format( + "" if path == "" else repr(path), + exc_info[1], + ) + + def validation_error(self, instance_path, error): + return self._error_format.format(file_name=instance_path, error=error) + + def validation_success(self, instance_path): + return "" def _namedAnyWithDefault(name): @@ -17,11 +136,6 @@ return namedAny(name) -def _json_file(path): - with open(path) as file: - return json.load(file) - - parser = argparse.ArgumentParser( description="JSON Schema Validation CLI", ) @@ -29,62 +143,142 @@ "-i", "--instance", action="append", dest="instances", - type=_json_file, - help=( - "a path to a JSON instance (i.e. filename.json) " - "to validate (may be specified multiple times)" - ), + help=""" + a path to a JSON instance (i.e. filename.json) to validate (may + be specified multiple times). If no instances are provided via this + option, one will be expected on standard input. + """, ) parser.add_argument( "-F", "--error-format", - default="{error.instance}: {error.message}\n", - help=( - "the format to use for each error output message, specified in " - "a form suitable for passing to str.format, which will be called " - "with 'error' for each error" - ), + help=""" + the format to use for each validation error message, specified + in a form suitable for str.format. This string will be passed + one formatted object named 'error' for each ValidationError. + Only provide this option when using --output=plain, which is the + default. If this argument is unprovided and --output=plain is + used, a simple default representation will be used. + """, +) +parser.add_argument( + "-o", "--output", + choices=["plain", "pretty"], + default="plain", + help=""" + an output format to use. 'plain' (default) will produce minimal + text with one line for each error, while 'pretty' will produce + more detailed human-readable output on multiple lines. + """, ) parser.add_argument( "-V", "--validator", type=_namedAnyWithDefault, - help=( - "the fully qualified object name of a validator to use, or, for " - "validators that are registered with jsonschema, simply the name " - "of the class." - ), + help=""" + the fully qualified object name of a validator to use, or, for + validators that are registered with jsonschema, simply the name + of the class. + """, +) +parser.add_argument( + "--base-uri", + help=""" + a base URI to assign to the provided schema, even if it does not + declare one (via e.g. $id). This option can be used if you wish to + resolve relative references to a particular URI (or local path) + """, ) parser.add_argument( "--version", action="version", - version=__version__, + version=metadata.version("jsonschema"), ) parser.add_argument( "schema", - help="the JSON Schema to validate with (i.e. schema.json)", - type=_json_file, + help="the path to a JSON Schema to validate with (i.e. schema.json)", ) def parse_args(args): arguments = vars(parser.parse_args(args=args or ["--help"])) - if arguments["validator"] is None: - arguments["validator"] = validator_for(arguments["schema"]) + if arguments["output"] != "plain" and arguments["error_format"]: + raise parser.error( + "--error-format can only be used with --output plain", + ) + if arguments["output"] == "plain" and arguments["error_format"] is None: + arguments["error_format"] = "{error.instance}: {error.message}\n" return arguments +def _validate_instance(instance_path, instance, validator, outputter): + invalid = False + for error in validator.iter_errors(instance): + invalid = True + outputter.validation_error(instance_path=instance_path, error=error) + + if not invalid: + outputter.validation_success(instance_path=instance_path) + return invalid + + def main(args=sys.argv[1:]): sys.exit(run(arguments=parse_args(args=args))) -def run(arguments, stdout=sys.stdout, stderr=sys.stderr): - error_format = arguments["error_format"] - validator = arguments["validator"](schema=arguments["schema"]) - - validator.check_schema(arguments["schema"]) - - errored = False - for instance in arguments["instances"] or (): - for error in validator.iter_errors(instance): - stderr.write(error_format.format(error=error)) - errored = True - return errored +def run(arguments, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin): + outputter = _Outputter.from_arguments( + arguments=arguments, + stdout=stdout, + stderr=stderr, + ) + + try: + schema = outputter.load(arguments["schema"]) + except _CannotLoadFile: + return 1 + + if arguments["validator"] is None: + arguments["validator"] = validator_for(schema) + + try: + arguments["validator"].check_schema(schema) + except SchemaError as error: + outputter.validation_error( + instance_path=arguments["schema"], + error=error, + ) + return 1 + + if arguments["instances"]: + load, instances = outputter.load, arguments["instances"] + else: + def load(_): + try: + return json.load(stdin) + except JSONDecodeError: + outputter.parsing_error( + path="", exc_info=sys.exc_info(), + ) + raise _CannotLoadFile() + instances = [""] + + resolver = RefResolver( + base_uri=arguments["base_uri"], + referrer=schema, + ) if arguments["base_uri"] is not None else None + + validator = arguments["validator"](schema, resolver=resolver) + exit_code = 0 + for each in instances: + try: + instance = load(each) + except _CannotLoadFile: + exit_code = 1 + else: + exit_code |= _validate_instance( + instance_path=each, + instance=instance, + validator=validator, + outputter=outputter, + ) + + return exit_code diff -Nru python-jsonschema-3.2.0/jsonschema/compat.py python-jsonschema-4.6.0/jsonschema/compat.py --- python-jsonschema-3.2.0/jsonschema/compat.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/compat.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -""" -Python 2/3 compatibility helpers. - -Note: This module is *not* public API. -""" -import contextlib -import operator -import sys - - -try: - from collections.abc import MutableMapping, Sequence # noqa -except ImportError: - from collections import MutableMapping, Sequence # noqa - -PY3 = sys.version_info[0] >= 3 - -if PY3: - zip = zip - from functools import lru_cache - from io import StringIO as NativeIO - from urllib.parse import ( - unquote, urljoin, urlunsplit, SplitResult, urlsplit - ) - from urllib.request import pathname2url, urlopen - str_types = str, - int_types = int, - iteritems = operator.methodcaller("items") -else: - from itertools import izip as zip # noqa - from io import BytesIO as NativeIO - from urlparse import urljoin, urlunsplit, SplitResult, urlsplit - from urllib import pathname2url, unquote # noqa - import urllib2 # noqa - def urlopen(*args, **kwargs): - return contextlib.closing(urllib2.urlopen(*args, **kwargs)) - - str_types = basestring - int_types = int, long - iteritems = operator.methodcaller("iteritems") - - from functools32 import lru_cache - - -def urldefrag(url): - if "#" in url: - s, n, p, q, frag = urlsplit(url) - defrag = urlunsplit((s, n, p, q, "")) - else: - defrag = url - frag = "" - return defrag, frag - - -# flake8: noqa diff -Nru python-jsonschema-3.2.0/jsonschema/exceptions.py python-jsonschema-4.6.0/jsonschema/exceptions.py --- python-jsonschema-3.2.0/jsonschema/exceptions.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/exceptions.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,19 +1,19 @@ """ Validation errors, and some surrounding helpers. """ +from __future__ import annotations + from collections import defaultdict, deque +from pprint import pformat +from textwrap import dedent, indent import itertools -import pprint -import textwrap import attr from jsonschema import _utils -from jsonschema.compat import PY3, iteritems - -WEAK_MATCHES = frozenset(["anyOf", "oneOf"]) -STRONG_MATCHES = frozenset() +WEAK_MATCHES: frozenset[str] = frozenset(["anyOf", "oneOf"]) +STRONG_MATCHES: frozenset[str] = frozenset() _unset = _utils.Unset() @@ -59,40 +59,36 @@ error.parent = self def __repr__(self): - return "<%s: %r>" % (self.__class__.__name__, self.message) + return f"<{self.__class__.__name__}: {self.message!r}>" - def __unicode__(self): + def __str__(self): essential_for_verbose = ( self.validator, self.validator_value, self.instance, self.schema, ) if any(m is _unset for m in essential_for_verbose): return self.message - pschema = pprint.pformat(self.schema, width=72) - pinstance = pprint.pformat(self.instance, width=72) - return self.message + textwrap.dedent(""" - - Failed validating %r in %s%s: - %s - - On %s%s: - %s - """.rstrip() - ) % ( - self.validator, - self._word_for_schema_in_error_message, - _utils.format_as_index(list(self.relative_schema_path)[:-1]), - _utils.indent(pschema), - self._word_for_instance_in_error_message, - _utils.format_as_index(self.relative_path), - _utils.indent(pinstance), + schema_path = _utils.format_as_index( + container=self._word_for_schema_in_error_message, + indices=list(self.relative_schema_path)[:-1], + ) + instance_path = _utils.format_as_index( + container=self._word_for_instance_in_error_message, + indices=self.relative_path, ) + prefix = 16 * " " - if PY3: - __str__ = __unicode__ - else: - def __str__(self): - return unicode(self).encode("utf-8") + return dedent( + f"""\ + {self.message} + + Failed validating {self.validator!r} in {schema_path}: + {indent(pformat(self.schema, width=72), prefix).lstrip()} + + On {instance_path}: + {indent(pformat(self.instance, width=72), prefix).lstrip()} + """.rstrip(), + ) @classmethod def create_from(cls, other): @@ -118,8 +114,18 @@ path.extendleft(reversed(parent.absolute_schema_path)) return path + @property + def json_path(self): + path = "$" + for elem in self.absolute_path: + if isinstance(elem, int): + path += "[" + str(elem) + "]" + else: + path += "." + elem + return path + def _set(self, **kwargs): - for k, v in iteritems(kwargs): + for k, v in kwargs.items(): if getattr(self, k) is _unset: setattr(self, k, v) @@ -169,14 +175,8 @@ def __init__(self, type): self.type = type - def __unicode__(self): - return "Type %r is unknown to this type checker" % self.type - - if PY3: - __str__ = __unicode__ - else: - def __str__(self): - return unicode(self).encode("utf-8") + def __str__(self): + return f"Type {self.type!r} is unknown to this type checker" class UnknownType(Exception): @@ -189,23 +189,18 @@ self.instance = instance self.schema = schema - def __unicode__(self): - pschema = pprint.pformat(self.schema, width=72) - pinstance = pprint.pformat(self.instance, width=72) - return textwrap.dedent(""" - Unknown type %r for validator with schema: - %s + def __str__(self): + prefix = 16 * " " + + return dedent( + f"""\ + Unknown type {self.type!r} for validator with schema: + {indent(pformat(self.schema, width=72), prefix).lstrip()} While checking instance: - %s - """.rstrip() - ) % (self.type, _utils.indent(pschema), _utils.indent(pinstance)) - - if PY3: - __str__ = __unicode__ - else: - def __str__(self): - return unicode(self).encode("utf-8") + {indent(pformat(self.instance, width=72), prefix).lstrip()} + """.rstrip(), + ) class FormatError(Exception): @@ -218,15 +213,9 @@ self.message = message self.cause = self.__cause__ = cause - def __unicode__(self): + def __str__(self): return self.message - if PY3: - __str__ = __unicode__ - else: - def __str__(self): - return self.message.encode("utf-8") - class ErrorTree(object): """ @@ -258,10 +247,10 @@ """ Retrieve the child tree one level down at the given ``index``. - If the index is not in the instance that this tree corresponds to and - is not known by this tree, whatever error would be raised by - ``instance.__getitem__`` will be propagated (usually this is some - subclass of `exceptions.LookupError`. + If the index is not in the instance that this tree corresponds + to and is not known by this tree, whatever error would be raised + by ``instance.__getitem__`` will be propagated (usually this is + some subclass of `LookupError`. """ if self._instance is not _unset and index not in self: @@ -288,7 +277,7 @@ return self.total_errors def __repr__(self): - return "<%s (%s total errors)>" % (self.__class__.__name__, len(self)) + return f"<{self.__class__.__name__} ({len(self)} total errors)>" @property def total_errors(self): @@ -296,7 +285,7 @@ The total number of errors in the entire tree, including children. """ - child_errors = sum(len(tree) for _, tree in iteritems(self._contents)) + child_errors = sum(len(tree) for _, tree in self._contents.items()) return len(self.errors) + child_errors @@ -339,14 +328,14 @@ not be relevant. Arguments: - errors (collections.Iterable): + errors (collections.abc.Iterable): the errors to select from. Do not provide a mixture of errors from different validation attempts (i.e. from different instances or schemas), since it won't produce sensical output. - key (collections.Callable): + key (collections.abc.Callable): the key to use when sorting errors. See `relevance` and transitively `by_relevance` for more details (the default is diff -Nru python-jsonschema-3.2.0/jsonschema/_format.py python-jsonschema-4.6.0/jsonschema/_format.py --- python-jsonschema-3.2.0/jsonschema/_format.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/_format.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,12 @@ +from __future__ import annotations + +from contextlib import suppress +from uuid import UUID import datetime +import ipaddress import re -import socket -import struct +import typing -from jsonschema.compat import str_types from jsonschema.exceptions import FormatError @@ -24,13 +27,19 @@ Arguments: - formats (~collections.Iterable): + formats (~collections.abc.Iterable): The known formats to validate. This argument can be used to limit which formats will be used during validation. """ - checkers = {} + checkers: dict[ + str, + tuple[ + typing.Callable[[typing.Any], bool], + Exception | tuple[Exception, ...], + ], + ] = {} def __init__(self, formats=None): if formats is None: @@ -98,9 +107,7 @@ except raises as e: cause = e if not result: - raise FormatError( - "%r is not a %r" % (instance, format), cause=cause, - ) + raise FormatError(f"{instance!r} is not a {format!r}", cause=cause) def conforms(self, instance, format): """ @@ -133,13 +140,16 @@ draft4_format_checker = FormatChecker() draft6_format_checker = FormatChecker() draft7_format_checker = FormatChecker() - +draft201909_format_checker = FormatChecker() +draft202012_format_checker = FormatChecker() _draft_checkers = dict( draft3=draft3_format_checker, draft4=draft4_format_checker, draft6=draft6_format_checker, draft7=draft7_format_checker, + draft201909=draft201909_format_checker, + draft202012=draft202012_format_checker, ) @@ -149,12 +159,16 @@ draft4=None, draft6=None, draft7=None, + draft201909=None, + draft202012=None, raises=(), ): draft3 = draft3 or name draft4 = draft4 or name draft6 = draft6 or name draft7 = draft7 or name + draft201909 = draft201909 or name + draft202012 = draft202012 or name def wrap(func): if draft3: @@ -165,13 +179,21 @@ func = _draft_checkers["draft6"].checks(draft6, raises)(func) if draft7: func = _draft_checkers["draft7"].checks(draft7, raises)(func) + if draft201909: + func = _draft_checkers["draft201909"].checks(draft201909, raises)( + func, + ) + if draft202012: + func = _draft_checkers["draft202012"].checks(draft202012, raises)( + func, + ) # Oy. This is bad global state, but relied upon for now, until - # deprecation. See https://github.com/Julian/jsonschema/issues/519 - # and test_format_checkers_come_with_defaults - FormatChecker.cls_checks(draft7 or draft6 or draft4 or draft3, raises)( - func, - ) + # deprecation. See #519 and test_format_checkers_come_with_defaults + FormatChecker.cls_checks( + draft202012 or draft201909 or draft7 or draft6 or draft4 or draft3, + raises, + )(func) return func return wrap @@ -179,67 +201,63 @@ @_checks_drafts(name="idn-email") @_checks_drafts(name="email") def is_email(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return "@" in instance -_ipv4_re = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") - - @_checks_drafts( - draft3="ip-address", draft4="ipv4", draft6="ipv4", draft7="ipv4", + draft3="ip-address", + draft4="ipv4", + draft6="ipv4", + draft7="ipv4", + draft201909="ipv4", + draft202012="ipv4", + raises=ipaddress.AddressValueError, ) def is_ipv4(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True - if not _ipv4_re.match(instance): - return False - return all(0 <= int(component) <= 255 for component in instance.split(".")) + return ipaddress.IPv4Address(instance) -if hasattr(socket, "inet_pton"): - # FIXME: Really this only should raise struct.error, but see the sadness - # that is https://twistedmatrix.com/trac/ticket/9409 - @_checks_drafts( - name="ipv6", raises=(socket.error, struct.error, ValueError), - ) - def is_ipv6(instance): - if not isinstance(instance, str_types): - return True - return socket.inet_pton(socket.AF_INET6, instance) - +@_checks_drafts(name="ipv6", raises=ipaddress.AddressValueError) +def is_ipv6(instance): + if not isinstance(instance, str): + return True + address = ipaddress.IPv6Address(instance) + return not getattr(address, "scope_id", "") -_host_name_re = re.compile(r"^[A-Za-z0-9][A-Za-z0-9\.\-]{1,255}$") +with suppress(ImportError): + from fqdn import FQDN -@_checks_drafts( - draft3="host-name", - draft4="hostname", - draft6="hostname", - draft7="hostname", -) -def is_host_name(instance): - if not isinstance(instance, str_types): - return True - if not _host_name_re.match(instance): - return False - components = instance.split(".") - for component in components: - if len(component) > 63: - return False - return True + @_checks_drafts( + draft3="host-name", + draft4="hostname", + draft6="hostname", + draft7="hostname", + draft201909="hostname", + draft202012="hostname", + ) + def is_host_name(instance): + if not isinstance(instance, str): + return True + return FQDN(instance).is_valid -try: +with suppress(ImportError): # The built-in `idna` codec only implements RFC 3890, so we go elsewhere. import idna -except ImportError: - pass -else: - @_checks_drafts(draft7="idn-hostname", raises=idna.IDNAError) + + @_checks_drafts( + draft7="idn-hostname", + draft201909="idn-hostname", + draft202012="idn-hostname", + raises=(idna.IDNAError, UnicodeError), + ) def is_idn_host_name(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True idna.encode(instance) return True @@ -248,135 +266,144 @@ try: import rfc3987 except ImportError: - try: + with suppress(ImportError): from rfc3986_validator import validate_rfc3986 - except ImportError: - pass - else: + @_checks_drafts(name="uri") def is_uri(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return validate_rfc3986(instance, rule="URI") @_checks_drafts( draft6="uri-reference", draft7="uri-reference", + draft201909="uri-reference", + draft202012="uri-reference", raises=ValueError, ) def is_uri_reference(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return validate_rfc3986(instance, rule="URI_reference") else: - @_checks_drafts(draft7="iri", raises=ValueError) + @_checks_drafts( + draft7="iri", + draft201909="iri", + draft202012="iri", + raises=ValueError, + ) def is_iri(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return rfc3987.parse(instance, rule="IRI") - @_checks_drafts(draft7="iri-reference", raises=ValueError) + @_checks_drafts( + draft7="iri-reference", + draft201909="iri-reference", + draft202012="iri-reference", + raises=ValueError, + ) def is_iri_reference(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return rfc3987.parse(instance, rule="IRI_reference") @_checks_drafts(name="uri", raises=ValueError) def is_uri(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return rfc3987.parse(instance, rule="URI") @_checks_drafts( draft6="uri-reference", draft7="uri-reference", + draft201909="uri-reference", + draft202012="uri-reference", raises=ValueError, ) def is_uri_reference(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return rfc3987.parse(instance, rule="URI_reference") +with suppress(ImportError): + from rfc3339_validator import validate_rfc3339 -try: - from strict_rfc3339 import validate_rfc3339 -except ImportError: - try: - from rfc3339_validator import validate_rfc3339 - except ImportError: - validate_rfc3339 = None - -if validate_rfc3339: @_checks_drafts(name="date-time") def is_datetime(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True - return validate_rfc3339(instance) + return validate_rfc3339(instance.upper()) - @_checks_drafts(draft7="time") + @_checks_drafts( + draft7="time", + draft201909="time", + draft202012="time", + ) def is_time(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return is_datetime("1970-01-01T" + instance) @_checks_drafts(name="regex", raises=re.error) def is_regex(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return re.compile(instance) -@_checks_drafts(draft3="date", draft7="date", raises=ValueError) +@_checks_drafts( + draft3="date", + draft7="date", + draft201909="date", + draft202012="date", + raises=ValueError, +) def is_date(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True - return datetime.datetime.strptime(instance, "%Y-%m-%d") + return instance.isascii() and datetime.date.fromisoformat(instance) @_checks_drafts(draft3="time", raises=ValueError) def is_draft3_time(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return datetime.datetime.strptime(instance, "%H:%M:%S") -try: +with suppress(ImportError): + from webcolors import CSS21_NAMES_TO_HEX import webcolors -except ImportError: - pass -else: + def is_css_color_code(instance): return webcolors.normalize_hex(instance) @_checks_drafts(draft3="color", raises=(ValueError, TypeError)) def is_css21_color(instance): if ( - not isinstance(instance, str_types) or - instance.lower() in webcolors.css21_names_to_hex + not isinstance(instance, str) + or instance.lower() in CSS21_NAMES_TO_HEX ): return True return is_css_color_code(instance) - def is_css3_color(instance): - if instance.lower() in webcolors.css3_names_to_hex: - return True - return is_css_color_code(instance) - -try: +with suppress(ImportError): import jsonpointer -except ImportError: - pass -else: + @_checks_drafts( draft6="json-pointer", draft7="json-pointer", + draft201909="json-pointer", + draft202012="json-pointer", raises=jsonpointer.JsonPointerException, ) def is_json_pointer(instance): - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True return jsonpointer.JsonPointer(instance) @@ -386,16 +413,22 @@ # into a new external library. @_checks_drafts( draft7="relative-json-pointer", + draft201909="relative-json-pointer", + draft202012="relative-json-pointer", raises=jsonpointer.JsonPointerException, ) def is_relative_json_pointer(instance): # Definition taken from: # https://tools.ietf.org/html/draft-handrews-relative-json-pointer-01#section-3 - if not isinstance(instance, str_types): + if not isinstance(instance, str): return True non_negative_integer, rest = [], "" for i, character in enumerate(instance): if character.isdigit(): + # digits with a leading "0" are not allowed + if i > 0 and int(instance[i - 1]) == 0: + return False + non_negative_integer.append(character) continue @@ -407,19 +440,42 @@ return (rest == "#") or jsonpointer.JsonPointer(rest) -try: - import uritemplate.exceptions -except ImportError: - pass -else: +with suppress(ImportError): + import uri_template + @_checks_drafts( draft6="uri-template", draft7="uri-template", - raises=uritemplate.exceptions.InvalidTemplate, + draft201909="uri-template", + draft202012="uri-template", ) - def is_uri_template( - instance, - template_validator=uritemplate.Validator().force_balanced_braces(), - ): - template = uritemplate.URITemplate(instance) - return template_validator.validate(template) + def is_uri_template(instance): + if not isinstance(instance, str): + return True + return uri_template.validate(instance) + + +with suppress(ImportError): + import isoduration + + @_checks_drafts( + draft201909="duration", + draft202012="duration", + raises=isoduration.DurationParsingException, + ) + def is_duration(instance): + if not isinstance(instance, str): + return True + return isoduration.parse_duration(instance) + + +@_checks_drafts( + draft201909="uuid", + draft202012="uuid", + raises=ValueError, +) +def is_uuid(instance): + if not isinstance(instance, str): + return True + UUID(instance) + return all(instance[position] == "-" for position in (8, 13, 18, 23)) diff -Nru python-jsonschema-3.2.0/jsonschema/__init__.py python-jsonschema-4.6.0/jsonschema/__init__.py --- python-jsonschema-3.2.0/jsonschema/__init__.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/__init__.py 2022-06-01 20:26:26.000000000 +0000 @@ -7,28 +7,52 @@ Most commonly, `validate` is the quickest way to simply validate a given instance under a schema, and will create a validator for you. """ +import warnings -from jsonschema.exceptions import ( - ErrorTree, FormatError, RefResolutionError, SchemaError, ValidationError -) from jsonschema._format import ( FormatChecker, draft3_format_checker, draft4_format_checker, draft6_format_checker, draft7_format_checker, + draft201909_format_checker, + draft202012_format_checker, ) from jsonschema._types import TypeChecker +from jsonschema.exceptions import ( + ErrorTree, + FormatError, + RefResolutionError, + SchemaError, + ValidationError, +) +from jsonschema.protocols import Validator from jsonschema.validators import ( Draft3Validator, Draft4Validator, Draft6Validator, Draft7Validator, + Draft201909Validator, + Draft202012Validator, RefResolver, validate, ) -try: - from importlib import metadata -except ImportError: # for Python<3.8 - import importlib_metadata as metadata -__version__ = metadata.version("jsonschema") + + +def __getattr__(name): + if name == "__version__": + warnings.warn( + "Accessing jsonschema.__version__ is deprecated and will be " + "removed in a future release. Use importlib.metadata directly " + "to query for jsonschema's version.", + DeprecationWarning, + stacklevel=2, + ) + + try: + from importlib import metadata + except ImportError: + import importlib_metadata as metadata + + return metadata.version("jsonschema") + raise AttributeError(f"module {__name__} has no attribute {name}") diff -Nru python-jsonschema-3.2.0/jsonschema/_legacy_validators.py python-jsonschema-4.6.0/jsonschema/_legacy_validators.py --- python-jsonschema-3.2.0/jsonschema/_legacy_validators.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/_legacy_validators.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,49 +1,88 @@ from jsonschema import _utils -from jsonschema.compat import iteritems from jsonschema.exceptions import ValidationError +def ignore_ref_siblings(schema): + """ + Ignore siblings of ``$ref`` if it is present. + + Otherwise, return all validators. + + Suitable for use with `create`'s ``applicable_validators`` argument. + """ + ref = schema.get("$ref") + if ref is not None: + return [("$ref", ref)] + else: + return schema.items() + + def dependencies_draft3(validator, dependencies, instance, schema): if not validator.is_type(instance, "object"): return - for property, dependency in iteritems(dependencies): + for property, dependency in dependencies.items(): if property not in instance: continue if validator.is_type(dependency, "object"): - for error in validator.descend( + yield from validator.descend( instance, dependency, schema_path=property, - ): - yield error + ) elif validator.is_type(dependency, "string"): if dependency not in instance: - yield ValidationError( - "%r is a dependency of %r" % (dependency, property) - ) + message = f"{dependency!r} is a dependency of {property!r}" + yield ValidationError(message) else: for each in dependency: if each not in instance: - message = "%r is a dependency of %r" - yield ValidationError(message % (each, property)) + message = f"{each!r} is a dependency of {property!r}" + yield ValidationError(message) + + +def dependencies_draft4_draft6_draft7( + validator, + dependencies, + instance, + schema, +): + """ + Support for the ``dependencies`` validator from pre-draft 2019-09. + + In later drafts, the validator was split into separate + ``dependentRequired`` and ``dependentSchemas`` validators. + """ + if not validator.is_type(instance, "object"): + return + + for property, dependency in dependencies.items(): + if property not in instance: + continue + + if validator.is_type(dependency, "array"): + for each in dependency: + if each not in instance: + message = f"{each!r} is a dependency of {property!r}" + yield ValidationError(message) + else: + yield from validator.descend( + instance, dependency, schema_path=property, + ) def disallow_draft3(validator, disallow, instance, schema): for disallowed in _utils.ensure_list(disallow): - if validator.is_valid(instance, {"type": [disallowed]}): - yield ValidationError( - "%r is disallowed for %r" % (disallowed, instance) - ) + if validator.evolve(schema={"type": [disallowed]}).is_valid(instance): + message = f"{disallowed!r} is disallowed for {instance!r}" + yield ValidationError(message) def extends_draft3(validator, extends, instance, schema): if validator.is_type(extends, "object"): - for error in validator.descend(instance, extends): - yield error + yield from validator.descend(instance, extends) return for index, subschema in enumerate(extends): - for error in validator.descend(instance, subschema, schema_path=index): - yield error + yield from validator.descend(instance, subschema, schema_path=index) def items_draft3_draft4(validator, items, instance, schema): @@ -52,14 +91,26 @@ if validator.is_type(items, "object"): for index, item in enumerate(instance): - for error in validator.descend(item, items, path=index): - yield error + yield from validator.descend(item, items, path=index) else: for (index, item), subschema in zip(enumerate(instance), items): - for error in validator.descend( + yield from validator.descend( + item, subschema, path=index, schema_path=index, + ) + + +def items_draft6_draft7_draft201909(validator, items, instance, schema): + if not validator.is_type(instance, "array"): + return + + if validator.is_type(items, "array"): + for (index, item), subschema in zip(enumerate(instance), items): + yield from validator.descend( item, subschema, path=index, schema_path=index, - ): - yield error + ) + else: + for index, item in enumerate(instance): + yield from validator.descend(item, items, path=index) def minimum_draft3_draft4(validator, minimum, instance, schema): @@ -74,9 +125,8 @@ cmp = "less than" if failed: - yield ValidationError( - "%r is %s the minimum of %r" % (instance, cmp, minimum) - ) + message = f"{instance!r} is {cmp} the minimum of {minimum!r}" + yield ValidationError(message) def maximum_draft3_draft4(validator, maximum, instance, schema): @@ -91,26 +141,24 @@ cmp = "greater than" if failed: - yield ValidationError( - "%r is %s the maximum of %r" % (instance, cmp, maximum) - ) + message = f"{instance!r} is {cmp} the maximum of {maximum!r}" + yield ValidationError(message) def properties_draft3(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return - for property, subschema in iteritems(properties): + for property, subschema in properties.items(): if property in instance: - for error in validator.descend( + yield from validator.descend( instance[property], subschema, path=property, schema_path=property, - ): - yield error + ) elif subschema.get("required", False): - error = ValidationError("%r is a required property" % property) + error = ValidationError(f"{property!r} is a required property") error._set( validator="required", validator_value=subschema["required"], @@ -136,6 +184,41 @@ if validator.is_type(instance, type): return else: + reprs = [] + for type in types: + try: + reprs.append(repr(type["name"])) + except Exception: + reprs.append(repr(type)) yield ValidationError( - _utils.types_msg(instance, types), context=all_errors, + f"{instance!r} is not of type {', '.join(reprs)}", + context=all_errors, ) + + +def contains_draft6_draft7(validator, contains, instance, schema): + if not validator.is_type(instance, "array"): + return + + if not any( + validator.evolve(schema=contains).is_valid(element) + for element in instance + ): + yield ValidationError( + f"None of {instance!r} are valid under the given schema", + ) + + +def recursiveRef(validator, recursiveRef, instance, schema): + lookup_url, target = validator.resolver.resolution_scope, validator.schema + + for each in reversed(validator.resolver._scopes_stack[1:]): + lookup_url, next_target = validator.resolver.resolve(each) + if next_target.get("$recursiveAnchor"): + target = next_target + else: + break + + fragment = recursiveRef.lstrip("#") + subschema = validator.resolver.resolve_fragment(target, fragment) + yield from validator.descend(instance, subschema) diff -Nru python-jsonschema-3.2.0/jsonschema/__main__.py python-jsonschema-4.6.0/jsonschema/__main__.py --- python-jsonschema-3.2.0/jsonschema/__main__.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/__main__.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,2 +1,3 @@ from jsonschema.cli import main + main() diff -Nru python-jsonschema-3.2.0/jsonschema/protocols.py python-jsonschema-4.6.0/jsonschema/protocols.py --- python-jsonschema-3.2.0/jsonschema/protocols.py 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/protocols.py 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,171 @@ +""" +typing.Protocol classes for jsonschema interfaces. +""" + +# for reference material on Protocols, see +# https://www.python.org/dev/peps/pep-0544/ + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, ClassVar, Iterator +import sys + +# doing these imports with `try ... except ImportError` doesn't pass mypy +# checking because mypy sees `typing._SpecialForm` and +# `typing_extensions._SpecialForm` as incompatible +# +# see: +# https://mypy.readthedocs.io/en/stable/runtime_troubles.html#using-new-additions-to-the-typing-module +# https://github.com/python/mypy/issues/4427 +if sys.version_info >= (3, 8): + from typing import Protocol, runtime_checkable +else: + from typing_extensions import Protocol, runtime_checkable + +# in order for Sphinx to resolve references accurately from type annotations, +# it needs to see names like `jsonschema.TypeChecker` +# therefore, only import at type-checking time (to avoid circular references), +# but use `jsonschema` for any types which will otherwise not be resolvable +if TYPE_CHECKING: + import jsonschema + +from jsonschema.exceptions import ValidationError +from jsonschema.validators import RefResolver + +# For code authors working on the validator protocol, these are the three +# use-cases which should be kept in mind: +# +# 1. As a protocol class, it can be used in type annotations to describe the +# available methods and attributes of a validator +# 2. It is the source of autodoc for the validator documentation +# 3. It is runtime_checkable, meaning that it can be used in isinstance() +# checks. +# +# Since protocols are not base classes, isinstance() checking is limited in +# its capabilities. See docs on runtime_checkable for detail + + +@runtime_checkable +class Validator(Protocol): + """ + The protocol to which all validator classes should adhere. + + :argument schema: the schema that the validator object + will validate with. It is assumed to be valid, and providing + an invalid schema can lead to undefined behavior. See + `Validator.check_schema` to validate a schema first. + :argument resolver: an instance of `jsonschema.RefResolver` that will be + used to resolve :validator:`$ref` properties (JSON references). If + unprovided, one will be created. + :argument format_checker: an instance of `jsonschema.FormatChecker` + whose `jsonschema.FormatChecker.conforms` method will be called to + check and see if instances conform to each :validator:`format` + property present in the schema. If unprovided, no validation + will be done for :validator:`format`. Certain formats require + additional packages to be installed (ipv5, uri, color, date-time). + The required packages can be found at the bottom of this page. + """ + + #: An object representing the validator's meta schema (the schema that + #: describes valid schemas in the given version). + META_SCHEMA: ClassVar[dict] + + #: A mapping of validator names (`str`\s) to functions + #: that validate the validator property with that name. For more + #: information see `creating-validators`. + VALIDATORS: ClassVar[dict] + + #: A `jsonschema.TypeChecker` that will be used when validating + #: :validator:`type` properties in JSON schemas. + TYPE_CHECKER: ClassVar[jsonschema.TypeChecker] + + #: A `jsonschema.FormatChecker` that will be used when validating + #: :validator:`format` properties in JSON schemas. + FORMAT_CHECKER: ClassVar[jsonschema.FormatChecker] + + #: The schema that was passed in when initializing the object. + schema: dict | bool + + def __init__( + self, + schema: dict | bool, + resolver: RefResolver | None = None, + format_checker: jsonschema.FormatChecker | None = None, + ) -> None: + ... + + @classmethod + def check_schema(cls, schema: dict) -> None: + """ + Validate the given schema against the validator's `META_SCHEMA`. + + :raises: `jsonschema.exceptions.SchemaError` if the schema + is invalid + """ + + def is_type(self, instance: Any, type: str) -> bool: + """ + Check if the instance is of the given (JSON Schema) type. + + :type type: str + :rtype: bool + :raises: `jsonschema.exceptions.UnknownType` if ``type`` + is not a known type. + """ + + def is_valid(self, instance: dict) -> bool: + """ + Check if the instance is valid under the current `schema`. + + :rtype: bool + + >>> schema = {"maxItems" : 2} + >>> Draft3Validator(schema).is_valid([2, 3, 4]) + False + """ + + def iter_errors(self, instance: dict) -> Iterator[ValidationError]: + r""" + Lazily yield each of the validation errors in the given instance. + + :rtype: an `collections.abc.Iterable` of + `jsonschema.exceptions.ValidationError`\s + + >>> schema = { + ... "type" : "array", + ... "items" : {"enum" : [1, 2, 3]}, + ... "maxItems" : 2, + ... } + >>> v = Draft3Validator(schema) + >>> for error in sorted(v.iter_errors([2, 3, 4]), key=str): + ... print(error.message) + 4 is not one of [1, 2, 3] + [2, 3, 4] is too long + """ + + def validate(self, instance: dict) -> None: + """ + Check if the instance is valid under the current `schema`. + + :raises: `jsonschema.exceptions.ValidationError` if the + instance is invalid + + >>> schema = {"maxItems" : 2} + >>> Draft3Validator(schema).validate([2, 3, 4]) + Traceback (most recent call last): + ... + ValidationError: [2, 3, 4] is too long + """ + + def evolve(self, **kwargs) -> "Validator": + """ + Create a new validator like this one, but with given changes. + + Preserves all other attributes, so can be used to e.g. create a + validator with a different schema but with the same :validator:`$ref` + resolution behavior. + + >>> validator = Draft202012Validator({}) + >>> validator.evolve(schema={"type": "number"}) + Draft202012Validator(schema={'type': 'number'}, format_checker=None) + """ diff -Nru python-jsonschema-3.2.0/jsonschema/_reflect.py python-jsonschema-4.6.0/jsonschema/_reflect.py --- python-jsonschema-3.2.0/jsonschema/_reflect.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/_reflect.py 2022-06-01 20:26:26.000000000 +0000 @@ -9,8 +9,6 @@ import sys -from jsonschema.compat import PY3 - class _NoModuleFound(Exception): """ @@ -42,12 +40,8 @@ -if PY3: - def reraise(exception, traceback): - raise exception.with_traceback(traceback) -else: - exec("""def reraise(exception, traceback): - raise exception.__class__, exception, traceback""") +def reraise(exception, traceback): + raise exception.with_traceback(traceback) reraise.__doc__ = """ Re-raise an exception, with an optional traceback, in a way that is compatible diff -Nru python-jsonschema-3.2.0/jsonschema/schemas/draft2019-09.json python-jsonschema-4.6.0/jsonschema/schemas/draft2019-09.json --- python-jsonschema-3.2.0/jsonschema/schemas/draft2019-09.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/schemas/draft2019-09.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,42 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/schema", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/core": true, + "https://json-schema.org/draft/2019-09/vocab/applicator": true, + "https://json-schema.org/draft/2019-09/vocab/validation": true, + "https://json-schema.org/draft/2019-09/vocab/meta-data": true, + "https://json-schema.org/draft/2019-09/vocab/format": false, + "https://json-schema.org/draft/2019-09/vocab/content": true + }, + "$recursiveAnchor": true, + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format"}, + {"$ref": "meta/content"} + ], + "type": ["object", "boolean"], + "properties": { + "definitions": { + "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", + "type": "object", + "additionalProperties": { "$recursiveRef": "#" }, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$recursiveRef": "#" }, + { "$ref": "meta/validation#/$defs/stringArray" } + ] + } + } + } +} diff -Nru python-jsonschema-3.2.0/jsonschema/schemas/draft2020-12.json python-jsonschema-4.6.0/jsonschema/schemas/draft2020-12.json --- python-jsonschema-3.2.0/jsonschema/schemas/draft2020-12.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/schemas/draft2020-12.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/schema", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/core": true, + "https://json-schema.org/draft/2020-12/vocab/applicator": true, + "https://json-schema.org/draft/2020-12/vocab/unevaluated": true, + "https://json-schema.org/draft/2020-12/vocab/validation": true, + "https://json-schema.org/draft/2020-12/vocab/meta-data": true, + "https://json-schema.org/draft/2020-12/vocab/format-annotation": true, + "https://json-schema.org/draft/2020-12/vocab/content": true + }, + "$dynamicAnchor": "meta", + + "title": "Core and Validation specifications meta-schema", + "allOf": [ + {"$ref": "meta/core"}, + {"$ref": "meta/applicator"}, + {"$ref": "meta/unevaluated"}, + {"$ref": "meta/validation"}, + {"$ref": "meta/meta-data"}, + {"$ref": "meta/format-annotation"}, + {"$ref": "meta/content"} + ], + "type": ["object", "boolean"], + "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", + "properties": { + "definitions": { + "$comment": "\"definitions\" has been replaced by \"$defs\".", + "type": "object", + "additionalProperties": { "$dynamicRef": "#meta" }, + "deprecated": true, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.", + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$dynamicRef": "#meta" }, + { "$ref": "meta/validation#/$defs/stringArray" } + ] + }, + "deprecated": true, + "default": {} + }, + "$recursiveAnchor": { + "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".", + "$ref": "meta/core#/$defs/anchorString", + "deprecated": true + }, + "$recursiveRef": { + "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".", + "$ref": "meta/core#/$defs/uriReferenceString", + "deprecated": true + } + } +} diff -Nru python-jsonschema-3.2.0/jsonschema/schemas/draft3.json python-jsonschema-4.6.0/jsonschema/schemas/draft3.json --- python-jsonschema-3.2.0/jsonschema/schemas/draft3.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/schemas/draft3.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,199 +1,177 @@ { - "$schema": "http://json-schema.org/draft-03/schema#", - "dependencies": { - "exclusiveMaximum": "maximum", - "exclusiveMinimum": "minimum" - }, - "id": "http://json-schema.org/draft-03/schema#", - "properties": { - "$ref": { - "format": "uri", - "type": "string" - }, - "$schema": { - "format": "uri", - "type": "string" - }, - "additionalItems": { - "default": {}, - "type": [ - { - "$ref": "#" - }, - "boolean" - ] - }, - "additionalProperties": { - "default": {}, - "type": [ - { - "$ref": "#" - }, - "boolean" - ] - }, - "default": { - "type": "any" - }, - "dependencies": { - "additionalProperties": { - "items": { - "type": "string" - }, - "type": [ - "string", - "array", - { - "$ref": "#" - } - ] - }, - "default": {}, - "type": [ - "string", - "array", - "object" - ] - }, - "description": { - "type": "string" - }, - "disallow": { - "items": { - "type": [ - "string", - { - "$ref": "#" - } - ] - }, - "type": [ - "string", - "array" - ], - "uniqueItems": true - }, - "divisibleBy": { - "default": 1, - "exclusiveMinimum": true, - "minimum": 0, - "type": "number" - }, - "enum": { - "type": "array" - }, - "exclusiveMaximum": { - "default": false, - "type": "boolean" - }, - "exclusiveMinimum": { - "default": false, - "type": "boolean" - }, - "extends": { - "default": {}, - "items": { - "$ref": "#" - }, - "type": [ - { - "$ref": "#" - }, - "array" - ] - }, - "format": { - "type": "string" - }, - "id": { - "format": "uri", - "type": "string" - }, - "items": { - "default": {}, - "items": { - "$ref": "#" - }, - "type": [ - { - "$ref": "#" - }, - "array" - ] - }, - "maxDecimal": { - "minimum": 0, - "type": "number" - }, - "maxItems": { - "minimum": 0, - "type": "integer" - }, - "maxLength": { - "type": "integer" - }, - "maximum": { - "type": "number" - }, - "minItems": { - "default": 0, - "minimum": 0, - "type": "integer" - }, - "minLength": { - "default": 0, - "minimum": 0, - "type": "integer" - }, - "minimum": { - "type": "number" - }, - "pattern": { - "format": "regex", - "type": "string" - }, - "patternProperties": { - "additionalProperties": { - "$ref": "#" - }, - "default": {}, - "type": "object" - }, - "properties": { - "additionalProperties": { - "$ref": "#", - "type": "object" - }, - "default": {}, - "type": "object" - }, - "required": { - "default": false, - "type": "boolean" - }, - "title": { - "type": "string" - }, - "type": { - "default": "any", - "items": { - "type": [ - "string", - { - "$ref": "#" - } - ] - }, - "type": [ - "string", - "array" - ], - "uniqueItems": true - }, - "uniqueItems": { - "default": false, - "type": "boolean" - } - }, - "type": "object" + "$schema" : "http://json-schema.org/draft-03/schema#", + "id" : "http://json-schema.org/draft-03/schema#", + "type" : "object", + + "properties" : { + "type" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "uniqueItems" : true, + "default" : "any" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#", "type" : "object"}, + "default" : {} + }, + + "patternProperties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "default" : {} + }, + + "additionalProperties" : { + "type" : [{"$ref" : "#"}, "boolean"], + "default" : {} + }, + + "items" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "default" : {} + }, + + "additionalItems" : { + "type" : [{"$ref" : "#"}, "boolean"], + "default" : {} + }, + + "required" : { + "type" : "boolean", + "default" : false + }, + + "dependencies" : { + "type" : ["string", "array", "object"], + "additionalProperties" : { + "type" : ["string", "array", {"$ref" : "#"}], + "items" : { + "type" : "string" + } + }, + "default" : {} + }, + + "minimum" : { + "type" : "number" + }, + + "maximum" : { + "type" : "number" + }, + + "exclusiveMinimum" : { + "type" : "boolean", + "default" : false + }, + + "exclusiveMaximum" : { + "type" : "boolean", + "default" : false + }, + + "maxDecimal": { + "minimum": 0, + "type": "number" + }, + + "minItems" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxItems" : { + "type" : "integer", + "minimum" : 0 + }, + + "uniqueItems" : { + "type" : "boolean", + "default" : false + }, + + "pattern" : { + "type" : "string", + "format" : "regex" + }, + + "minLength" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxLength" : { + "type" : "integer" + }, + + "enum" : { + "type" : "array" + }, + + "default" : { + "type" : "any" + }, + + "title" : { + "type" : "string" + }, + + "description" : { + "type" : "string" + }, + + "format" : { + "type" : "string" + }, + + "divisibleBy" : { + "type" : "number", + "minimum" : 0, + "exclusiveMinimum" : true, + "default" : 1 + }, + + "disallow" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "uniqueItems" : true + }, + + "extends" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "default" : {} + }, + + "id" : { + "type" : "string", + "format" : "uri" + }, + + "$ref" : { + "type" : "string", + "format" : "uri" + }, + + "$schema" : { + "type" : "string", + "format" : "uri" + } + }, + + "dependencies" : { + "exclusiveMinimum" : "minimum", + "exclusiveMaximum" : "maximum" + }, + + "default" : {} } diff -Nru python-jsonschema-3.2.0/jsonschema/schemas/draft4.json python-jsonschema-4.6.0/jsonschema/schemas/draft4.json --- python-jsonschema-3.2.0/jsonschema/schemas/draft4.json 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/schemas/draft4.json 2022-06-01 20:26:26.000000000 +0000 @@ -1,222 +1,149 @@ { + "id": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#", - "default": {}, + "description": "Core schema meta-schema", "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#" } + }, "positiveInteger": { - "minimum": 0, - "type": "integer" + "type": "integer", + "minimum": 0 }, "positiveIntegerDefault0": { - "allOf": [ - { - "$ref": "#/definitions/positiveInteger" - }, - { - "default": 0 - } - ] - }, - "schemaArray": { - "items": { - "$ref": "#" - }, - "minItems": 1, - "type": "array" + "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] }, "simpleTypes": { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] + "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] }, "stringArray": { - "items": { - "type": "string" - }, - "minItems": 1, "type": "array", + "items": { "type": "string" }, + "minItems": 1, "uniqueItems": true } }, - "dependencies": { - "exclusiveMaximum": [ - "maximum" - ], - "exclusiveMinimum": [ - "minimum" - ] - }, - "description": "Core schema meta-schema", - "id": "http://json-schema.org/draft-04/schema#", + "type": "object", "properties": { - "$schema": { + "id": { "format": "uri", "type": "string" }, - "additionalItems": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#" - } - ], - "default": {} - }, - "additionalProperties": { - "anyOf": [ - { - "type": "boolean" - }, - { - "$ref": "#" - } - ], - "default": {} - }, - "allOf": { - "$ref": "#/definitions/schemaArray" - }, - "anyOf": { - "$ref": "#/definitions/schemaArray" - }, - "default": {}, - "definitions": { - "additionalProperties": { - "$ref": "#" - }, - "default": {}, - "type": "object" + "$schema": { + "type": "string", + "format": "uri" }, - "dependencies": { - "additionalProperties": { - "anyOf": [ - { - "$ref": "#" - }, - { - "$ref": "#/definitions/stringArray" - } - ] - }, - "type": "object" + "title": { + "type": "string" }, "description": { "type": "string" }, - "enum": { - "type": "array" + "default": {}, + "multipleOf": { + "type": "number", + "minimum": 0, + "exclusiveMinimum": true + }, + "maximum": { + "type": "number" }, "exclusiveMaximum": { - "default": false, - "type": "boolean" + "type": "boolean", + "default": false + }, + "minimum": { + "type": "number" }, "exclusiveMinimum": { - "default": false, - "type": "boolean" + "type": "boolean", + "default": false }, - "format": { - "type": "string" + "maxLength": { "$ref": "#/definitions/positiveInteger" }, + "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" }, - "id": { - "format": "uri", - "type": "string" + "additionalItems": { + "anyOf": [ + { "type": "boolean" }, + { "$ref": "#" } + ], + "default": {} }, "items": { "anyOf": [ - { - "$ref": "#" - }, - { - "$ref": "#/definitions/schemaArray" - } + { "$ref": "#" }, + { "$ref": "#/definitions/schemaArray" } ], "default": {} }, - "maxItems": { - "$ref": "#/definitions/positiveInteger" - }, - "maxLength": { - "$ref": "#/definitions/positiveInteger" - }, - "maxProperties": { - "$ref": "#/definitions/positiveInteger" - }, - "maximum": { - "type": "number" - }, - "minItems": { - "$ref": "#/definitions/positiveIntegerDefault0" - }, - "minLength": { - "$ref": "#/definitions/positiveIntegerDefault0" - }, - "minProperties": { - "$ref": "#/definitions/positiveIntegerDefault0" - }, - "minimum": { - "type": "number" - }, - "multipleOf": { - "exclusiveMinimum": true, - "minimum": 0, - "type": "number" + "maxItems": { "$ref": "#/definitions/positiveInteger" }, + "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false }, - "not": { - "$ref": "#" + "maxProperties": { "$ref": "#/definitions/positiveInteger" }, + "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "required": { "$ref": "#/definitions/stringArray" }, + "additionalProperties": { + "anyOf": [ + { "type": "boolean" }, + { "$ref": "#" } + ], + "default": {} }, - "oneOf": { - "$ref": "#/definitions/schemaArray" + "definitions": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} }, - "pattern": { - "format": "regex", - "type": "string" + "properties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} }, "patternProperties": { - "additionalProperties": { - "$ref": "#" - }, - "default": {}, - "type": "object" + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} }, - "properties": { + "dependencies": { + "type": "object", "additionalProperties": { - "$ref": "#" - }, - "default": {}, - "type": "object" - }, - "required": { - "$ref": "#/definitions/stringArray" + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/stringArray" } + ] + } }, - "title": { - "type": "string" + "enum": { + "type": "array" }, "type": { "anyOf": [ + { "$ref": "#/definitions/simpleTypes" }, { - "$ref": "#/definitions/simpleTypes" - }, - { - "items": { - "$ref": "#/definitions/simpleTypes" - }, - "minItems": 1, "type": "array", + "items": { "$ref": "#/definitions/simpleTypes" }, + "minItems": 1, "uniqueItems": true } ] }, - "uniqueItems": { - "default": false, - "type": "boolean" - } + "format": { "type": "string" }, + "allOf": { "$ref": "#/definitions/schemaArray" }, + "anyOf": { "$ref": "#/definitions/schemaArray" }, + "oneOf": { "$ref": "#/definitions/schemaArray" }, + "not": { "$ref": "#" } + }, + "dependencies": { + "exclusiveMaximum": [ "maximum" ], + "exclusiveMinimum": [ "minimum" ] }, - "type": "object" + "default": {} } diff -Nru python-jsonschema-3.2.0/jsonschema/schemas/vocabularies.json python-jsonschema-4.6.0/jsonschema/schemas/vocabularies.json --- python-jsonschema-3.2.0/jsonschema/schemas/vocabularies.json 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/schemas/vocabularies.json 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1 @@ +{"https://json-schema.org/draft/2020-12/meta/content": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/content", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/content": true}, "$dynamicAnchor": "meta", "title": "Content vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"contentEncoding": {"type": "string"}, "contentMediaType": {"type": "string"}, "contentSchema": {"$dynamicRef": "#meta"}}}, "https://json-schema.org/draft/2020-12/meta/unevaluated": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/unevaluated", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/unevaluated": true}, "$dynamicAnchor": "meta", "title": "Unevaluated applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"unevaluatedItems": {"$dynamicRef": "#meta"}, "unevaluatedProperties": {"$dynamicRef": "#meta"}}}, "https://json-schema.org/draft/2020-12/meta/format-annotation": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/format-annotation", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/format-annotation": true}, "$dynamicAnchor": "meta", "title": "Format vocabulary meta-schema for annotation results", "type": ["object", "boolean"], "properties": {"format": {"type": "string"}}}, "https://json-schema.org/draft/2020-12/meta/applicator": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/applicator", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/applicator": true}, "$dynamicAnchor": "meta", "title": "Applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"prefixItems": {"$ref": "#/$defs/schemaArray"}, "items": {"$dynamicRef": "#meta"}, "contains": {"$dynamicRef": "#meta"}, "additionalProperties": {"$dynamicRef": "#meta"}, "properties": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}, "default": {}}, "patternProperties": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}, "propertyNames": {"format": "regex"}, "default": {}}, "dependentSchemas": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}, "default": {}}, "propertyNames": {"$dynamicRef": "#meta"}, "if": {"$dynamicRef": "#meta"}, "then": {"$dynamicRef": "#meta"}, "else": {"$dynamicRef": "#meta"}, "allOf": {"$ref": "#/$defs/schemaArray"}, "anyOf": {"$ref": "#/$defs/schemaArray"}, "oneOf": {"$ref": "#/$defs/schemaArray"}, "not": {"$dynamicRef": "#meta"}}, "$defs": {"schemaArray": {"type": "array", "minItems": 1, "items": {"$dynamicRef": "#meta"}}}}, "https://json-schema.org/draft/2020-12/meta/meta-data": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/meta-data", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/meta-data": true}, "$dynamicAnchor": "meta", "title": "Meta-data vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"title": {"type": "string"}, "description": {"type": "string"}, "default": true, "deprecated": {"type": "boolean", "default": false}, "readOnly": {"type": "boolean", "default": false}, "writeOnly": {"type": "boolean", "default": false}, "examples": {"type": "array", "items": true}}}, "https://json-schema.org/draft/2020-12/meta/core": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/core", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/core": true}, "$dynamicAnchor": "meta", "title": "Core vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"$id": {"$ref": "#/$defs/uriReferenceString", "$comment": "Non-empty fragments not allowed.", "pattern": "^[^#]*#?$"}, "$schema": {"$ref": "#/$defs/uriString"}, "$ref": {"$ref": "#/$defs/uriReferenceString"}, "$anchor": {"$ref": "#/$defs/anchorString"}, "$dynamicRef": {"$ref": "#/$defs/uriReferenceString"}, "$dynamicAnchor": {"$ref": "#/$defs/anchorString"}, "$vocabulary": {"type": "object", "propertyNames": {"$ref": "#/$defs/uriString"}, "additionalProperties": {"type": "boolean"}}, "$comment": {"type": "string"}, "$defs": {"type": "object", "additionalProperties": {"$dynamicRef": "#meta"}}}, "$defs": {"anchorString": {"type": "string", "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$"}, "uriString": {"type": "string", "format": "uri"}, "uriReferenceString": {"type": "string", "format": "uri-reference"}}}, "https://json-schema.org/draft/2020-12/meta/validation": {"$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://json-schema.org/draft/2020-12/meta/validation", "$vocabulary": {"https://json-schema.org/draft/2020-12/vocab/validation": true}, "$dynamicAnchor": "meta", "title": "Validation vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"type": {"anyOf": [{"$ref": "#/$defs/simpleTypes"}, {"type": "array", "items": {"$ref": "#/$defs/simpleTypes"}, "minItems": 1, "uniqueItems": true}]}, "const": true, "enum": {"type": "array", "items": true}, "multipleOf": {"type": "number", "exclusiveMinimum": 0}, "maximum": {"type": "number"}, "exclusiveMaximum": {"type": "number"}, "minimum": {"type": "number"}, "exclusiveMinimum": {"type": "number"}, "maxLength": {"$ref": "#/$defs/nonNegativeInteger"}, "minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "pattern": {"type": "string", "format": "regex"}, "maxItems": {"$ref": "#/$defs/nonNegativeInteger"}, "minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "uniqueItems": {"type": "boolean", "default": false}, "maxContains": {"$ref": "#/$defs/nonNegativeInteger"}, "minContains": {"$ref": "#/$defs/nonNegativeInteger", "default": 1}, "maxProperties": {"$ref": "#/$defs/nonNegativeInteger"}, "minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "required": {"$ref": "#/$defs/stringArray"}, "dependentRequired": {"type": "object", "additionalProperties": {"$ref": "#/$defs/stringArray"}}}, "$defs": {"nonNegativeInteger": {"type": "integer", "minimum": 0}, "nonNegativeIntegerDefault0": {"$ref": "#/$defs/nonNegativeInteger", "default": 0}, "simpleTypes": {"enum": ["array", "boolean", "integer", "null", "number", "object", "string"]}, "stringArray": {"type": "array", "items": {"type": "string"}, "uniqueItems": true, "default": []}}}, "https://json-schema.org/draft/2019-09/meta/content": {"$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/content", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/content": true}, "$recursiveAnchor": true, "title": "Content vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"contentMediaType": {"type": "string"}, "contentEncoding": {"type": "string"}, "contentSchema": {"$recursiveRef": "#"}}}, "https://json-schema.org/draft/2019-09/meta/applicator": {"$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/applicator", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/applicator": true}, "$recursiveAnchor": true, "title": "Applicator vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"additionalItems": {"$recursiveRef": "#"}, "unevaluatedItems": {"$recursiveRef": "#"}, "items": {"anyOf": [{"$recursiveRef": "#"}, {"$ref": "#/$defs/schemaArray"}]}, "contains": {"$recursiveRef": "#"}, "additionalProperties": {"$recursiveRef": "#"}, "unevaluatedProperties": {"$recursiveRef": "#"}, "properties": {"type": "object", "additionalProperties": {"$recursiveRef": "#"}, "default": {}}, "patternProperties": {"type": "object", "additionalProperties": {"$recursiveRef": "#"}, "propertyNames": {"format": "regex"}, "default": {}}, "dependentSchemas": {"type": "object", "additionalProperties": {"$recursiveRef": "#"}}, "propertyNames": {"$recursiveRef": "#"}, "if": {"$recursiveRef": "#"}, "then": {"$recursiveRef": "#"}, "else": {"$recursiveRef": "#"}, "allOf": {"$ref": "#/$defs/schemaArray"}, "anyOf": {"$ref": "#/$defs/schemaArray"}, "oneOf": {"$ref": "#/$defs/schemaArray"}, "not": {"$recursiveRef": "#"}}, "$defs": {"schemaArray": {"type": "array", "minItems": 1, "items": {"$recursiveRef": "#"}}}}, "https://json-schema.org/draft/2019-09/meta/meta-data": {"$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/meta-data": true}, "$recursiveAnchor": true, "title": "Meta-data vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"title": {"type": "string"}, "description": {"type": "string"}, "default": true, "deprecated": {"type": "boolean", "default": false}, "readOnly": {"type": "boolean", "default": false}, "writeOnly": {"type": "boolean", "default": false}, "examples": {"type": "array", "items": true}}}, "https://json-schema.org/draft/2019-09/meta/core": {"$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/core", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/core": true}, "$recursiveAnchor": true, "title": "Core vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"$id": {"type": "string", "format": "uri-reference", "$comment": "Non-empty fragments not allowed.", "pattern": "^[^#]*#?$"}, "$schema": {"type": "string", "format": "uri"}, "$anchor": {"type": "string", "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$"}, "$ref": {"type": "string", "format": "uri-reference"}, "$recursiveRef": {"type": "string", "format": "uri-reference"}, "$recursiveAnchor": {"type": "boolean", "default": false}, "$vocabulary": {"type": "object", "propertyNames": {"type": "string", "format": "uri"}, "additionalProperties": {"type": "boolean"}}, "$comment": {"type": "string"}, "$defs": {"type": "object", "additionalProperties": {"$recursiveRef": "#"}, "default": {}}}}, "https://json-schema.org/draft/2019-09/meta/validation": {"$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/validation", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/validation": true}, "$recursiveAnchor": true, "title": "Validation vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"multipleOf": {"type": "number", "exclusiveMinimum": 0}, "maximum": {"type": "number"}, "exclusiveMaximum": {"type": "number"}, "minimum": {"type": "number"}, "exclusiveMinimum": {"type": "number"}, "maxLength": {"$ref": "#/$defs/nonNegativeInteger"}, "minLength": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "pattern": {"type": "string", "format": "regex"}, "maxItems": {"$ref": "#/$defs/nonNegativeInteger"}, "minItems": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "uniqueItems": {"type": "boolean", "default": false}, "maxContains": {"$ref": "#/$defs/nonNegativeInteger"}, "minContains": {"$ref": "#/$defs/nonNegativeInteger", "default": 1}, "maxProperties": {"$ref": "#/$defs/nonNegativeInteger"}, "minProperties": {"$ref": "#/$defs/nonNegativeIntegerDefault0"}, "required": {"$ref": "#/$defs/stringArray"}, "dependentRequired": {"type": "object", "additionalProperties": {"$ref": "#/$defs/stringArray"}}, "const": true, "enum": {"type": "array", "items": true}, "type": {"anyOf": [{"$ref": "#/$defs/simpleTypes"}, {"type": "array", "items": {"$ref": "#/$defs/simpleTypes"}, "minItems": 1, "uniqueItems": true}]}}, "$defs": {"nonNegativeInteger": {"type": "integer", "minimum": 0}, "nonNegativeIntegerDefault0": {"$ref": "#/$defs/nonNegativeInteger", "default": 0}, "simpleTypes": {"enum": ["array", "boolean", "integer", "null", "number", "object", "string"]}, "stringArray": {"type": "array", "items": {"type": "string"}, "uniqueItems": true, "default": []}}}, "https://json-schema.org/draft/2019-09/meta/hyper-schema": {"$schema": "https://json-schema.org/draft/2019-09/hyper-schema", "$id": "https://json-schema.org/draft/2019-09/meta/hyper-schema", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/hyper-schema": true}, "$recursiveAnchor": true, "title": "JSON Hyper-Schema Vocabulary Schema", "type": ["object", "boolean"], "properties": {"base": {"type": "string", "format": "uri-template"}, "links": {"type": "array", "items": {"$ref": "https://json-schema.org/draft/2019-09/links"}}}, "links": [{"rel": "self", "href": "{+%24id}"}]}, "https://json-schema.org/draft/2019-09/meta/format": {"$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "https://json-schema.org/draft/2019-09/meta/format", "$vocabulary": {"https://json-schema.org/draft/2019-09/vocab/format": true}, "$recursiveAnchor": true, "title": "Format vocabulary meta-schema", "type": ["object", "boolean"], "properties": {"format": {"type": "string"}}}} diff -Nru python-jsonschema-3.2.0/jsonschema/tests/fuzz_validate.py python-jsonschema-4.6.0/jsonschema/tests/fuzz_validate.py --- python-jsonschema-3.2.0/jsonschema/tests/fuzz_validate.py 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/fuzz_validate.py 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,49 @@ +""" +Fuzzing setup for OSS-Fuzz. + +See https://github.com/google/oss-fuzz/tree/master/projects/jsonschema for the +other half of the setup here. +""" +import sys + +from hypothesis import given, strategies + +import jsonschema + +PRIM = strategies.one_of( + strategies.booleans(), + strategies.integers(), + strategies.floats(allow_nan=False, allow_infinity=False), + strategies.text(), +) +DICT = strategies.recursive( + base=strategies.one_of( + strategies.booleans(), + strategies.dictionaries(strategies.text(), PRIM), + ), + extend=lambda inner: strategies.dictionaries(strategies.text(), inner), +) + + +@given(obj1=DICT, obj2=DICT) +def test_schemas(obj1, obj2): + try: + jsonschema.validate(instance=obj1, schema=obj2) + except jsonschema.exceptions.ValidationError: + pass + except jsonschema.exceptions.SchemaError: + pass + + +def main(): + atheris.Setup( + sys.argv, + test_schemas.hypothesis.fuzz_one_input, + enable_python_coverage=True, + ) + atheris.Fuzz() + + +if __name__ == "__main__": + import atheris + main() diff -Nru python-jsonschema-3.2.0/jsonschema/tests/_suite.py python-jsonschema-4.6.0/jsonschema/tests/_suite.py --- python-jsonschema-3.2.0/jsonschema/tests/_suite.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/_suite.py 2022-06-01 20:26:26.000000000 +0000 @@ -3,6 +3,7 @@ """ from functools import partial +from pathlib import Path import json import os import re @@ -10,21 +11,19 @@ import sys import unittest -from twisted.python.filepath import FilePath import attr -from jsonschema.compat import PY3 -from jsonschema.validators import validators +from jsonschema.validators import _VALIDATORS import jsonschema def _find_suite(): root = os.environ.get("JSON_SCHEMA_TEST_SUITE") if root is not None: - return FilePath(root) + return Path(root) - root = FilePath(jsonschema.__file__).parent().sibling("json") - if not root.isdir(): # pragma: no cover + root = Path(jsonschema.__file__).parent.parent / "json" + if not root.is_dir(): # pragma: no cover raise ValueError( ( "Can't find the JSON-Schema-Test-Suite directory. " @@ -42,23 +41,26 @@ _root = attr.ib(default=attr.Factory(_find_suite)) def _remotes(self): - jsonschema_suite = self._root.descendant(["bin", "jsonschema_suite"]) + jsonschema_suite = self._root.joinpath("bin", "jsonschema_suite") remotes = subprocess.check_output( - [sys.executable, jsonschema_suite.path, "remotes"], + [sys.executable, str(jsonschema_suite), "remotes"], ) return { - "http://localhost:1234/" + name: schema + "http://localhost:1234/" + name.replace("\\", "/"): schema for name, schema in json.loads(remotes.decode("utf-8")).items() } def benchmark(self, runner): # pragma: no cover - for name in validators: - self.version(name=name).benchmark(runner=runner) + for name, Validator in _VALIDATORS.items(): + self.version(name=name).benchmark( + runner=runner, + Validator=Validator, + ) def version(self, name): return Version( name=name, - path=self._root.descendant(["tests", name]), + path=self._root.joinpath("tests", name), remotes=self._remotes(), ) @@ -82,38 +84,32 @@ def tests(self): return ( test - for child in self._path.globChildren("*.json") + for child in self._path.glob("*.json") for test in self._tests_in( - subject=child.basename()[:-5], + subject=child.name[:-5], path=child, ) ) def format_tests(self): - path = self._path.descendant(["optional", "format"]) + path = self._path.joinpath("optional", "format") return ( test - for child in path.globChildren("*.json") + for child in path.glob("*.json") for test in self._tests_in( - subject=child.basename()[:-5], + subject=child.name[:-5], path=child, ) ) - def tests_of(self, name): - return self._tests_in( - subject=name, - path=self._path.child(name + ".json"), - ) - def optional_tests_of(self, name): return self._tests_in( subject=name, - path=self._path.descendant(["optional", name + ".json"]), + path=self._path.joinpath("optional", name + ".json"), ) def to_unittest_testcase(self, *suites, **kwargs): - name = kwargs.pop("name", "Test" + self.name.title()) + name = kwargs.pop("name", "Test" + self.name.title().replace("-", "")) methods = { test.method_name: test.to_unittest_method(**kwargs) for suite in suites @@ -133,7 +129,7 @@ return cls def _tests_in(self, subject, path): - for each in json.loads(path.getContent().decode("utf-8")): + for each in json.loads(path.read_text(encoding="utf-8")): yield ( _Test( version=self, @@ -141,7 +137,7 @@ case_description=each["description"], schema=each["schema"], remotes=self._remotes, - **test + **test, ) for test in each["tests"] ) @@ -162,6 +158,8 @@ _remotes = attr.ib() + comment = attr.ib(default=None) + def __repr__(self): # pragma: no cover return "".format(self.fully_qualified_name) @@ -173,22 +171,18 @@ self.subject, self.case_description, self.description, - ] + ], ) @property def method_name(self): delimiters = r"[\W\- ]+" - name = "test_%s_%s_%s" % ( + return "test_{}_{}_{}".format( re.sub(delimiters, "_", self.subject), re.sub(delimiters, "_", self.case_description), re.sub(delimiters, "_", self.description), ) - if not PY3: # pragma: no cover - name = name.encode("utf-8") - return name - def to_unittest_method(self, skip=lambda test: None, **kwargs): if self.valid: def fn(this): @@ -208,13 +202,8 @@ store=self._remotes, id_of=Validator.ID_OF, ) - jsonschema.validate( - instance=self.data, - schema=self.schema, - cls=Validator, - resolver=resolver, - **kwargs - ) + validator = Validator(schema=self.schema, resolver=resolver, **kwargs) + validator.validate(instance=self.data) def validate_ignoring_errors(self, Validator): # pragma: no cover try: diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_cli.py python-jsonschema-4.6.0/jsonschema/tests/test_cli.py --- python-jsonschema-3.2.0/jsonschema/tests/test_cli.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_cli.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,11 +1,29 @@ +from contextlib import redirect_stderr, redirect_stdout +from io import StringIO +from json import JSONDecodeError +from pathlib import Path +from textwrap import dedent from unittest import TestCase import json +import os import subprocess import sys +import tempfile -from jsonschema import Draft4Validator, ValidationError, cli, __version__ -from jsonschema.compat import NativeIO -from jsonschema.exceptions import SchemaError +try: # pragma: no cover + from importlib import metadata +except ImportError: # pragma: no cover + import importlib_metadata as metadata # type: ignore + +from pyrsistent import m + +from jsonschema import Draft4Validator, Draft202012Validator, cli +from jsonschema.exceptions import ( + RefResolutionError, + SchemaError, + ValidationError, +) +from jsonschema.validators import _LATEST_VERSION, validate def fake_validator(*errors): @@ -18,41 +36,812 @@ def iter_errors(self, instance): if errors: return errors.pop() - return [] + return [] # pragma: no cover + @classmethod def check_schema(self, schema): pass return FakeValidator +def fake_open(all_contents): + def open(path): + contents = all_contents.get(path) + if contents is None: + raise FileNotFoundError(path) + return StringIO(contents) + return open + + +def _message_for(non_json): + try: + json.loads(non_json) + except JSONDecodeError as error: + return str(error) + else: # pragma: no cover + raise RuntimeError("Tried and failed to capture a JSON dump error.") + + +class TestCLI(TestCase): + def run_cli( + self, argv, files=m(), stdin=StringIO(), exit_code=0, **override, + ): + arguments = cli.parse_args(argv) + arguments.update(override) + + self.assertFalse(hasattr(cli, "open")) + cli.open = fake_open(files) + try: + stdout, stderr = StringIO(), StringIO() + actual_exit_code = cli.run( + arguments, + stdin=stdin, + stdout=stdout, + stderr=stderr, + ) + finally: + del cli.open + + self.assertEqual( + actual_exit_code, exit_code, msg=dedent( + """ + Expected an exit code of {} != {}. + + stdout: {} + + stderr: {} + """.format( + exit_code, + actual_exit_code, + stdout.getvalue(), + stderr.getvalue(), + ), + ), + ) + return stdout.getvalue(), stderr.getvalue() + + def assertOutputs(self, stdout="", stderr="", **kwargs): + self.assertEqual( + self.run_cli(**kwargs), + (dedent(stdout), dedent(stderr)), + ) + + def test_invalid_instance(self): + error = ValidationError("I am an error!", instance=12) + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_instance=json.dumps(error.instance), + ), + validator=fake_validator([error]), + + argv=["-i", "some_instance", "some_schema"], + + exit_code=1, + stderr="12: I am an error!\n", + ) + + def test_invalid_instance_pretty_output(self): + error = ValidationError("I am an error!", instance=12) + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_instance=json.dumps(error.instance), + ), + validator=fake_validator([error]), + + argv=["-i", "some_instance", "--output", "pretty", "some_schema"], + + exit_code=1, + stderr="""\ + ===[ValidationError]===(some_instance)=== + + I am an error! + ----------------------------- + """, + ) + + def test_invalid_instance_explicit_plain_output(self): + error = ValidationError("I am an error!", instance=12) + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_instance=json.dumps(error.instance), + ), + validator=fake_validator([error]), + + argv=["--output", "plain", "-i", "some_instance", "some_schema"], + + exit_code=1, + stderr="12: I am an error!\n", + ) + + def test_invalid_instance_multiple_errors(self): + instance = 12 + first = ValidationError("First error", instance=instance) + second = ValidationError("Second error", instance=instance) + + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_instance=json.dumps(instance), + ), + validator=fake_validator([first, second]), + + argv=["-i", "some_instance", "some_schema"], + + exit_code=1, + stderr="""\ + 12: First error + 12: Second error + """, + ) + + def test_invalid_instance_multiple_errors_pretty_output(self): + instance = 12 + first = ValidationError("First error", instance=instance) + second = ValidationError("Second error", instance=instance) + + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_instance=json.dumps(instance), + ), + validator=fake_validator([first, second]), + + argv=["-i", "some_instance", "--output", "pretty", "some_schema"], + + exit_code=1, + stderr="""\ + ===[ValidationError]===(some_instance)=== + + First error + ----------------------------- + ===[ValidationError]===(some_instance)=== + + Second error + ----------------------------- + """, + ) + + def test_multiple_invalid_instances(self): + first_instance = 12 + first_errors = [ + ValidationError("An error", instance=first_instance), + ValidationError("Another error", instance=first_instance), + ] + second_instance = "foo" + second_errors = [ValidationError("BOOM", instance=second_instance)] + + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_first_instance=json.dumps(first_instance), + some_second_instance=json.dumps(second_instance), + ), + validator=fake_validator(first_errors, second_errors), + + argv=[ + "-i", "some_first_instance", + "-i", "some_second_instance", + "some_schema", + ], + + exit_code=1, + stderr="""\ + 12: An error + 12: Another error + foo: BOOM + """, + ) + + def test_multiple_invalid_instances_pretty_output(self): + first_instance = 12 + first_errors = [ + ValidationError("An error", instance=first_instance), + ValidationError("Another error", instance=first_instance), + ] + second_instance = "foo" + second_errors = [ValidationError("BOOM", instance=second_instance)] + + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_first_instance=json.dumps(first_instance), + some_second_instance=json.dumps(second_instance), + ), + validator=fake_validator(first_errors, second_errors), + + argv=[ + "--output", "pretty", + "-i", "some_first_instance", + "-i", "some_second_instance", + "some_schema", + ], + + exit_code=1, + stderr="""\ + ===[ValidationError]===(some_first_instance)=== + + An error + ----------------------------- + ===[ValidationError]===(some_first_instance)=== + + Another error + ----------------------------- + ===[ValidationError]===(some_second_instance)=== + + BOOM + ----------------------------- + """, + ) + + def test_custom_error_format(self): + first_instance = 12 + first_errors = [ + ValidationError("An error", instance=first_instance), + ValidationError("Another error", instance=first_instance), + ] + second_instance = "foo" + second_errors = [ValidationError("BOOM", instance=second_instance)] + + self.assertOutputs( + files=dict( + some_schema='{"does not": "matter since it is stubbed"}', + some_first_instance=json.dumps(first_instance), + some_second_instance=json.dumps(second_instance), + ), + validator=fake_validator(first_errors, second_errors), + + argv=[ + "--error-format", ":{error.message}._-_.{error.instance}:", + "-i", "some_first_instance", + "-i", "some_second_instance", + "some_schema", + ], + + exit_code=1, + stderr=":An error._-_.12::Another error._-_.12::BOOM._-_.foo:", + ) + + def test_invalid_schema(self): + self.assertOutputs( + files=dict(some_schema='{"type": 12}'), + argv=["some_schema"], + + exit_code=1, + stderr="""\ + 12: 12 is not valid under any of the given schemas + """, + ) + + def test_invalid_schema_pretty_output(self): + schema = {"type": 12} + + with self.assertRaises(SchemaError) as e: + validate(schema=schema, instance="") + error = str(e.exception) + + self.assertOutputs( + files=dict(some_schema=json.dumps(schema)), + argv=["--output", "pretty", "some_schema"], + + exit_code=1, + stderr=( + "===[SchemaError]===(some_schema)===\n\n" + + str(error) + + "\n-----------------------------\n" + ), + ) + + def test_invalid_schema_multiple_errors(self): + self.assertOutputs( + files=dict(some_schema='{"type": 12, "items": 57}'), + argv=["some_schema"], + + exit_code=1, + stderr="""\ + 57: 57 is not of type 'object', 'boolean' + """, + ) + + def test_invalid_schema_multiple_errors_pretty_output(self): + schema = {"type": 12, "items": 57} + + with self.assertRaises(SchemaError) as e: + validate(schema=schema, instance="") + error = str(e.exception) + + self.assertOutputs( + files=dict(some_schema=json.dumps(schema)), + argv=["--output", "pretty", "some_schema"], + + exit_code=1, + stderr=( + "===[SchemaError]===(some_schema)===\n\n" + + str(error) + + "\n-----------------------------\n" + ), + ) + + def test_invalid_schema_with_invalid_instance(self): + """ + "Validating" an instance that's invalid under an invalid schema + just shows the schema error. + """ + self.assertOutputs( + files=dict( + some_schema='{"type": 12, "minimum": 30}', + some_instance="13", + ), + argv=["-i", "some_instance", "some_schema"], + + exit_code=1, + stderr="""\ + 12: 12 is not valid under any of the given schemas + """, + ) + + def test_invalid_schema_with_invalid_instance_pretty_output(self): + instance, schema = 13, {"type": 12, "minimum": 30} + + with self.assertRaises(SchemaError) as e: + validate(schema=schema, instance=instance) + error = str(e.exception) + + self.assertOutputs( + files=dict( + some_schema=json.dumps(schema), + some_instance=json.dumps(instance), + ), + argv=["--output", "pretty", "-i", "some_instance", "some_schema"], + + exit_code=1, + stderr=( + "===[SchemaError]===(some_schema)===\n\n" + + str(error) + + "\n-----------------------------\n" + ), + ) + + def test_invalid_instance_continues_with_the_rest(self): + self.assertOutputs( + files=dict( + some_schema='{"minimum": 30}', + first_instance="not valid JSON!", + second_instance="12", + ), + argv=[ + "-i", "first_instance", + "-i", "second_instance", + "some_schema", + ], + + exit_code=1, + stderr="""\ + Failed to parse 'first_instance': {} + 12: 12 is less than the minimum of 30 + """.format(_message_for("not valid JSON!")), + ) + + def test_custom_error_format_applies_to_schema_errors(self): + instance, schema = 13, {"type": 12, "minimum": 30} + + with self.assertRaises(SchemaError): + validate(schema=schema, instance=instance) + + self.assertOutputs( + files=dict(some_schema=json.dumps(schema)), + + argv=[ + "--error-format", ":{error.message}._-_.{error.instance}:", + "some_schema", + ], + + exit_code=1, + stderr=":12 is not valid under any of the given schemas._-_.12:", + ) + + def test_instance_is_invalid_JSON(self): + instance = "not valid JSON!" + + self.assertOutputs( + files=dict(some_schema="{}", some_instance=instance), + argv=["-i", "some_instance", "some_schema"], + + exit_code=1, + stderr="""\ + Failed to parse 'some_instance': {} + """.format(_message_for(instance)), + ) + + def test_instance_is_invalid_JSON_pretty_output(self): + stdout, stderr = self.run_cli( + files=dict( + some_schema="{}", + some_instance="not valid JSON!", + ), + + argv=["--output", "pretty", "-i", "some_instance", "some_schema"], + + exit_code=1, + ) + self.assertFalse(stdout) + self.assertIn( + "(some_instance)===\n\nTraceback (most recent call last):\n", + stderr, + ) + self.assertNotIn("some_schema", stderr) + + def test_instance_is_invalid_JSON_on_stdin(self): + instance = "not valid JSON!" + + self.assertOutputs( + files=dict(some_schema="{}"), + stdin=StringIO(instance), + + argv=["some_schema"], + + exit_code=1, + stderr="""\ + Failed to parse : {} + """.format(_message_for(instance)), + ) + + def test_instance_is_invalid_JSON_on_stdin_pretty_output(self): + stdout, stderr = self.run_cli( + files=dict(some_schema="{}"), + stdin=StringIO("not valid JSON!"), + + argv=["--output", "pretty", "some_schema"], + + exit_code=1, + ) + self.assertFalse(stdout) + self.assertIn( + "()===\n\nTraceback (most recent call last):\n", + stderr, + ) + self.assertNotIn("some_schema", stderr) + + def test_schema_is_invalid_JSON(self): + schema = "not valid JSON!" + + self.assertOutputs( + files=dict(some_schema=schema), + + argv=["some_schema"], + + exit_code=1, + stderr="""\ + Failed to parse 'some_schema': {} + """.format(_message_for(schema)), + ) + + def test_schema_is_invalid_JSON_pretty_output(self): + stdout, stderr = self.run_cli( + files=dict(some_schema="not valid JSON!"), + + argv=["--output", "pretty", "some_schema"], + + exit_code=1, + ) + self.assertFalse(stdout) + self.assertIn( + "(some_schema)===\n\nTraceback (most recent call last):\n", + stderr, + ) + + def test_schema_and_instance_are_both_invalid_JSON(self): + """ + Only the schema error is reported, as we abort immediately. + """ + schema, instance = "not valid JSON!", "also not valid JSON!" + self.assertOutputs( + files=dict(some_schema=schema, some_instance=instance), + + argv=["some_schema"], + + exit_code=1, + stderr="""\ + Failed to parse 'some_schema': {} + """.format(_message_for(schema)), + ) + + def test_schema_and_instance_are_both_invalid_JSON_pretty_output(self): + """ + Only the schema error is reported, as we abort immediately. + """ + stdout, stderr = self.run_cli( + files=dict( + some_schema="not valid JSON!", + some_instance="also not valid JSON!", + ), + + argv=["--output", "pretty", "-i", "some_instance", "some_schema"], + + exit_code=1, + ) + self.assertFalse(stdout) + self.assertIn( + "(some_schema)===\n\nTraceback (most recent call last):\n", + stderr, + ) + self.assertNotIn("some_instance", stderr) + + def test_instance_does_not_exist(self): + self.assertOutputs( + files=dict(some_schema="{}"), + argv=["-i", "nonexisting_instance", "some_schema"], + + exit_code=1, + stderr="""\ + 'nonexisting_instance' does not exist. + """, + ) + + def test_instance_does_not_exist_pretty_output(self): + self.assertOutputs( + files=dict(some_schema="{}"), + argv=[ + "--output", "pretty", + "-i", "nonexisting_instance", + "some_schema", + ], + + exit_code=1, + stderr="""\ + ===[FileNotFoundError]===(nonexisting_instance)=== + + 'nonexisting_instance' does not exist. + ----------------------------- + """, + ) + + def test_schema_does_not_exist(self): + self.assertOutputs( + argv=["nonexisting_schema"], + + exit_code=1, + stderr="'nonexisting_schema' does not exist.\n", + ) + + def test_schema_does_not_exist_pretty_output(self): + self.assertOutputs( + argv=["--output", "pretty", "nonexisting_schema"], + + exit_code=1, + stderr="""\ + ===[FileNotFoundError]===(nonexisting_schema)=== + + 'nonexisting_schema' does not exist. + ----------------------------- + """, + ) + + def test_neither_instance_nor_schema_exist(self): + self.assertOutputs( + argv=["-i", "nonexisting_instance", "nonexisting_schema"], + + exit_code=1, + stderr="'nonexisting_schema' does not exist.\n", + ) + + def test_neither_instance_nor_schema_exist_pretty_output(self): + self.assertOutputs( + argv=[ + "--output", "pretty", + "-i", "nonexisting_instance", + "nonexisting_schema", + ], + + exit_code=1, + stderr="""\ + ===[FileNotFoundError]===(nonexisting_schema)=== + + 'nonexisting_schema' does not exist. + ----------------------------- + """, + ) + + def test_successful_validation(self): + self.assertOutputs( + files=dict(some_schema="{}", some_instance="{}"), + argv=["-i", "some_instance", "some_schema"], + stdout="", + stderr="", + ) + + def test_successful_validation_pretty_output(self): + self.assertOutputs( + files=dict(some_schema="{}", some_instance="{}"), + argv=["--output", "pretty", "-i", "some_instance", "some_schema"], + stdout="===[SUCCESS]===(some_instance)===\n", + stderr="", + ) + + def test_successful_validation_of_stdin(self): + self.assertOutputs( + files=dict(some_schema="{}"), + stdin=StringIO("{}"), + argv=["some_schema"], + stdout="", + stderr="", + ) + + def test_successful_validation_of_stdin_pretty_output(self): + self.assertOutputs( + files=dict(some_schema="{}"), + stdin=StringIO("{}"), + argv=["--output", "pretty", "some_schema"], + stdout="===[SUCCESS]===()===\n", + stderr="", + ) + + def test_successful_validation_of_just_the_schema(self): + self.assertOutputs( + files=dict(some_schema="{}", some_instance="{}"), + argv=["-i", "some_instance", "some_schema"], + stdout="", + stderr="", + ) + + def test_successful_validation_of_just_the_schema_pretty_output(self): + self.assertOutputs( + files=dict(some_schema="{}", some_instance="{}"), + argv=["--output", "pretty", "-i", "some_instance", "some_schema"], + stdout="===[SUCCESS]===(some_instance)===\n", + stderr="", + ) + + def test_successful_validation_via_explicit_base_uri(self): + ref_schema_file = tempfile.NamedTemporaryFile(delete=False) + self.addCleanup(os.remove, ref_schema_file.name) + + ref_path = Path(ref_schema_file.name) + ref_path.write_text('{"definitions": {"num": {"type": "integer"}}}') + + schema = f'{{"$ref": "{ref_path.name}#definitions/num"}}' + + self.assertOutputs( + files=dict(some_schema=schema, some_instance="1"), + argv=[ + "-i", "some_instance", + "--base-uri", ref_path.parent.as_uri() + "/", + "some_schema", + ], + stdout="", + stderr="", + ) + + def test_unsuccessful_validation_via_explicit_base_uri(self): + ref_schema_file = tempfile.NamedTemporaryFile(delete=False) + self.addCleanup(os.remove, ref_schema_file.name) + + ref_path = Path(ref_schema_file.name) + ref_path.write_text('{"definitions": {"num": {"type": "integer"}}}') + + schema = f'{{"$ref": "{ref_path.name}#definitions/num"}}' + + self.assertOutputs( + files=dict(some_schema=schema, some_instance='"1"'), + argv=[ + "-i", "some_instance", + "--base-uri", ref_path.parent.as_uri() + "/", + "some_schema", + ], + exit_code=1, + stdout="", + stderr="1: '1' is not of type 'integer'\n", + ) + + def test_nonexistent_file_with_explicit_base_uri(self): + schema = '{"$ref": "someNonexistentFile.json#definitions/num"}' + instance = "1" + + with self.assertRaises(RefResolutionError) as e: + self.assertOutputs( + files=dict( + some_schema=schema, + some_instance=instance, + ), + argv=[ + "-i", "some_instance", + "--base-uri", Path.cwd().as_uri(), + "some_schema", + ], + ) + error = str(e.exception) + self.assertIn(f"{os.sep}someNonexistentFile.json'", error) + + def test_invalid_exlicit_base_uri(self): + schema = '{"$ref": "foo.json#definitions/num"}' + instance = "1" + + with self.assertRaises(RefResolutionError) as e: + self.assertOutputs( + files=dict( + some_schema=schema, + some_instance=instance, + ), + argv=[ + "-i", "some_instance", + "--base-uri", "not@UR1", + "some_schema", + ], + ) + error = str(e.exception) + self.assertEqual( + error, "unknown url type: 'foo.json'", + ) + + def test_it_validates_using_the_latest_validator_when_unspecified(self): + # There isn't a better way now I can think of to ensure that the + # latest version was used, given that the call to validator_for + # is hidden inside the CLI, so guard that that's the case, and + # this test will have to be updated when versions change until + # we can think of a better way to ensure this behavior. + self.assertIs(Draft202012Validator, _LATEST_VERSION) + + self.assertOutputs( + files=dict(some_schema='{"const": "check"}', some_instance='"a"'), + argv=["-i", "some_instance", "some_schema"], + exit_code=1, + stdout="", + stderr="a: 'check' was expected\n", + ) + + def test_it_validates_using_draft7_when_specified(self): + """ + Specifically, `const` validation applies for Draft 7. + """ + schema = """ + { + "$schema": "http://json-schema.org/draft-07/schema#", + "const": "check" + } + """ + instance = '"foo"' + self.assertOutputs( + files=dict(some_schema=schema, some_instance=instance), + argv=["-i", "some_instance", "some_schema"], + exit_code=1, + stdout="", + stderr="foo: 'check' was expected\n", + ) + + def test_it_validates_using_draft4_when_specified(self): + """ + Specifically, `const` validation *does not* apply for Draft 4. + """ + schema = """ + { + "$schema": "http://json-schema.org/draft-04/schema#", + "const": "check" + } + """ + instance = '"foo"' + self.assertOutputs( + files=dict(some_schema=schema, some_instance=instance), + argv=["-i", "some_instance", "some_schema"], + stdout="", + stderr="", + ) + + class TestParser(TestCase): FakeValidator = fake_validator() - instance_file = "foo.json" - schema_file = "schema.json" - - def setUp(self): - cli.open = self.fake_open - self.addCleanup(delattr, cli, "open") - - def fake_open(self, path): - if path == self.instance_file: - contents = "" - elif path == self.schema_file: - contents = {} - else: # pragma: no cover - self.fail("What is {!r}".format(path)) - return NativeIO(json.dumps(contents)) def test_find_validator_by_fully_qualified_object_name(self): arguments = cli.parse_args( [ "--validator", "jsonschema.tests.test_cli.TestParser.FakeValidator", - "--instance", self.instance_file, - self.schema_file, - ] + "--instance", "mem://some/instance", + "mem://some/schema", + ], ) self.assertIs(arguments["validator"], self.FakeValidator) @@ -60,87 +849,47 @@ arguments = cli.parse_args( [ "--validator", "Draft4Validator", - "--instance", self.instance_file, - self.schema_file, - ] + "--instance", "mem://some/instance", + "mem://some/schema", + ], ) self.assertIs(arguments["validator"], Draft4Validator) + def cli_output_for(self, *argv): + stdout, stderr = StringIO(), StringIO() + with redirect_stdout(stdout), redirect_stderr(stderr): + with self.assertRaises(SystemExit): + cli.parse_args(argv) + return stdout.getvalue(), stderr.getvalue() + + def test_unknown_output(self): + stdout, stderr = self.cli_output_for( + "--output", "foo", + "mem://some/schema", + ) + self.assertIn("invalid choice: 'foo'", stderr) + self.assertFalse(stdout) -class TestCLI(TestCase): - def test_draft3_schema_draft4_validator(self): - stdout, stderr = NativeIO(), NativeIO() - with self.assertRaises(SchemaError): - cli.run( - { - "validator": Draft4Validator, - "schema": { - "anyOf": [ - {"minimum": 20}, - {"type": "string"}, - {"required": True}, - ], - }, - "instances": [1], - "error_format": "{error.message}", - }, - stdout=stdout, - stderr=stderr, - ) + def test_useless_error_format(self): + stdout, stderr = self.cli_output_for( + "--output", "pretty", + "--error-format", "foo", + "mem://some/schema", + ) + self.assertIn( + "--error-format can only be used with --output plain", + stderr, + ) + self.assertFalse(stdout) - def test_successful_validation(self): - stdout, stderr = NativeIO(), NativeIO() - exit_code = cli.run( - { - "validator": fake_validator(), - "schema": {}, - "instances": [1], - "error_format": "{error.message}", - }, - stdout=stdout, - stderr=stderr, - ) - self.assertFalse(stdout.getvalue()) - self.assertFalse(stderr.getvalue()) - self.assertEqual(exit_code, 0) - - def test_unsuccessful_validation(self): - error = ValidationError("I am an error!", instance=1) - stdout, stderr = NativeIO(), NativeIO() - exit_code = cli.run( - { - "validator": fake_validator([error]), - "schema": {}, - "instances": [1], - "error_format": "{error.instance} - {error.message}", - }, - stdout=stdout, - stderr=stderr, - ) - self.assertFalse(stdout.getvalue()) - self.assertEqual(stderr.getvalue(), "1 - I am an error!") - self.assertEqual(exit_code, 1) - def test_unsuccessful_validation_multiple_instances(self): - first_errors = [ - ValidationError("9", instance=1), - ValidationError("8", instance=1), - ] - second_errors = [ValidationError("7", instance=2)] - stdout, stderr = NativeIO(), NativeIO() - exit_code = cli.run( - { - "validator": fake_validator(first_errors, second_errors), - "schema": {}, - "instances": [1, 2], - "error_format": "{error.instance} - {error.message}\t", - }, - stdout=stdout, - stderr=stderr, - ) - self.assertFalse(stdout.getvalue()) - self.assertEqual(stderr.getvalue(), "1 - 9\t1 - 8\t2 - 7\t") - self.assertEqual(exit_code, 1) +class TestCLIIntegration(TestCase): + def test_license(self): + output = subprocess.check_output( + [sys.executable, "-m", "pip", "show", "jsonschema"], + stderr=subprocess.STDOUT, + ) + self.assertIn(b"License: MIT", output) def test_version(self): version = subprocess.check_output( @@ -148,4 +897,15 @@ stderr=subprocess.STDOUT, ) version = version.decode("utf-8").strip() - self.assertEqual(version, __version__) + self.assertEqual(version, metadata.version("jsonschema")) + + def test_no_arguments_shows_usage_notes(self): + output = subprocess.check_output( + [sys.executable, "-m", "jsonschema"], + stderr=subprocess.STDOUT, + ) + output_for_help = subprocess.check_output( + [sys.executable, "-m", "jsonschema", "--help"], + stderr=subprocess.STDOUT, + ) + self.assertEqual(output, output_for_help) diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_deprecations.py python-jsonschema-4.6.0/jsonschema/tests/test_deprecations.py --- python-jsonschema-3.2.0/jsonschema/tests/test_deprecations.py 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_deprecations.py 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,123 @@ +from unittest import TestCase + +from jsonschema import validators + + +class TestDeprecations(TestCase): + def test_version(self): + """ + As of v4.0.0, __version__ is deprecated in favor of importlib.metadata. + """ + + with self.assertWarns(DeprecationWarning) as w: + from jsonschema import __version__ # noqa + + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "Accessing jsonschema.__version__ is deprecated", + ), + ) + + def test_validators_ErrorTree(self): + """ + As of v4.0.0, importing ErrorTree from jsonschema.validators is + deprecated in favor of doing so from jsonschema.exceptions. + """ + + with self.assertWarns(DeprecationWarning) as w: + from jsonschema.validators import ErrorTree # noqa + + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "Importing ErrorTree from jsonschema.validators is deprecated", + ), + ) + + def test_validators_validators(self): + """ + As of v4.0.0, accessing jsonschema.validators.validators is + deprecated. + """ + + with self.assertWarns(DeprecationWarning) as w: + value = validators.validators + self.assertEqual(value, validators._VALIDATORS) + + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "Accessing jsonschema.validators.validators is deprecated", + ), + ) + + def test_validators_meta_schemas(self): + """ + As of v4.0.0, accessing jsonschema.validators.meta_schemas is + deprecated. + """ + + with self.assertWarns(DeprecationWarning) as w: + value = validators.meta_schemas + self.assertEqual(value, validators._META_SCHEMAS) + + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "Accessing jsonschema.validators.meta_schemas is deprecated", + ), + ) + + def test_RefResolver_in_scope(self): + """ + As of v4.0.0, RefResolver.in_scope is deprecated. + """ + + resolver = validators.RefResolver.from_schema({}) + with self.assertWarns(DeprecationWarning) as w: + with resolver.in_scope("foo"): + pass + + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "jsonschema.RefResolver.in_scope is deprecated ", + ), + ) + + def test_Validator_is_valid_two_arguments(self): + """ + As of v4.0.0, calling is_valid with two arguments (to provide a + different schema) is deprecated. + """ + + validator = validators.Draft7Validator({}) + with self.assertWarns(DeprecationWarning) as w: + result = validator.is_valid("foo", {"type": "number"}) + + self.assertFalse(result) + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "Passing a schema to Validator.is_valid is deprecated ", + ), + ) + + def test_Validator_iter_errors_two_arguments(self): + """ + As of v4.0.0, calling iter_errors with two arguments (to provide a + different schema) is deprecated. + """ + + validator = validators.Draft7Validator({}) + with self.assertWarns(DeprecationWarning) as w: + error, = validator.iter_errors("foo", {"type": "number"}) + + self.assertEqual(error.validator, "type") + self.assertEqual(w.filename, __file__) + self.assertTrue( + str(w.warning).startswith( + "Passing a schema to Validator.iter_errors is deprecated ", + ), + ) diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_exceptions.py python-jsonschema-4.6.0/jsonschema/tests/test_exceptions.py --- python-jsonschema-3.2.0/jsonschema/tests/test_exceptions.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_exceptions.py 2022-06-01 20:26:26.000000000 +0000 @@ -2,7 +2,6 @@ import textwrap from jsonschema import Draft4Validator, exceptions -from jsonschema.compat import PY3 class TestBestMatch(TestCase): @@ -42,7 +41,7 @@ "minProperties": 2, "anyOf": [{"type": "string"}, {"type": "number"}], "oneOf": [{"type": "string"}, {"type": "number"}], - } + }, ) best = self.best_match(validator.iter_errors({})) self.assertEqual(best.validator, "minProperties") @@ -210,7 +209,7 @@ class TestErrorTree(TestCase): def test_it_knows_how_many_total_errors_it_contains(self): - # FIXME: https://github.com/Julian/jsonschema/issues/442 + # FIXME: #442 errors = [ exceptions.ValidationError("Something", validator=i) for i in range(8) @@ -285,22 +284,36 @@ tree = exceptions.ErrorTree([error]) self.assertIsInstance(tree["foo"], exceptions.ErrorTree) + def test_repr(self): + e1, e2 = ( + exceptions.ValidationError( + "1", + validator="foo", + path=["bar", "bar2"], + instance="i1"), + exceptions.ValidationError( + "2", + validator="quux", + path=["foobar", 2], + instance="i2"), + ) + tree = exceptions.ErrorTree([e1, e2]) + self.assertEqual(repr(tree), "") + class TestErrorInitReprStr(TestCase): def make_error(self, **kwargs): defaults = dict( - message=u"hello", - validator=u"type", - validator_value=u"string", + message="hello", + validator="type", + validator_value="string", instance=5, - schema={u"type": u"string"}, + schema={"type": "string"}, ) defaults.update(kwargs) return exceptions.ValidationError(**defaults) def assertShows(self, expected, **kwargs): - if PY3: # pragma: no cover - expected = expected.replace("u'", "'") expected = textwrap.dedent(expected).rstrip("\n") error = self.make_error(**kwargs) @@ -315,7 +328,7 @@ def test_repr(self): self.assertEqual( repr(exceptions.ValidationError(message="Hello!")), - "" % "Hello!", + "", ) def test_unset_error(self): @@ -338,8 +351,8 @@ def test_empty_paths(self): self.assertShows( """ - Failed validating u'type' in schema: - {u'type': u'string'} + Failed validating 'type' in schema: + {'type': 'string'} On instance: 5 @@ -351,8 +364,8 @@ def test_one_item_paths(self): self.assertShows( """ - Failed validating u'type' in schema: - {u'type': u'string'} + Failed validating 'type' in schema: + {'type': 'string'} On instance[0]: 5 @@ -364,20 +377,20 @@ def test_multiple_item_paths(self): self.assertShows( """ - Failed validating u'type' in schema[u'items'][0]: - {u'type': u'string'} + Failed validating 'type' in schema['items'][0]: + {'type': 'string'} - On instance[0][u'a']: + On instance[0]['a']: 5 """, - path=[0, u"a"], - schema_path=[u"items", 0, 1], + path=[0, "a"], + schema_path=["items", 0, 1], ) def test_uses_pprint(self): self.assertShows( """ - Failed validating u'maxLength' in schema: + Failed validating 'maxLength' in schema: {0: 0, 1: 1, 2: 2, @@ -428,14 +441,14 @@ """, instance=list(range(25)), schema=dict(zip(range(20), range(20))), - validator=u"maxLength", + validator="maxLength", ) def test_str_works_with_instances_having_overriden_eq_operator(self): """ - Check for https://github.com/Julian/jsonschema/issues/164 which - rendered exceptions unusable when a `ValidationError` involved - instances with an `__eq__` method that returned truthy values. + Check for #164 which rendered exceptions unusable when a + `ValidationError` involved instances with an `__eq__` method + that returned truthy values. """ class DontEQMeBro(object): diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_format.py python-jsonschema-4.6.0/jsonschema/tests/test_format.py --- python-jsonschema-3.2.0/jsonschema/tests/test_format.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_format.py 2022-06-01 20:26:26.000000000 +0000 @@ -4,10 +4,9 @@ from unittest import TestCase -from jsonschema import FormatError, ValidationError, FormatChecker +from jsonschema import FormatChecker, FormatError, ValidationError from jsonschema.validators import Draft4Validator - BOOM = ValueError("Boom!") BANG = ZeroDivisionError("Bang!") @@ -41,7 +40,7 @@ checker.checks("boom")(boom) self.assertEqual( checker.checkers, - dict(FormatChecker.checkers, boom=(boom, ())) + dict(FormatChecker.checkers, boom=(boom, ())), ) def test_it_catches_registered_errors(self): @@ -80,10 +79,29 @@ def test_repr(self): checker = FormatChecker(formats=()) - checker.checks("foo")(lambda thing: True) - checker.checks("bar")(lambda thing: True) - checker.checks("baz")(lambda thing: True) + checker.checks("foo")(lambda thing: True) # pragma: no cover + checker.checks("bar")(lambda thing: True) # pragma: no cover + checker.checks("baz")(lambda thing: True) # pragma: no cover self.assertEqual( repr(checker), "", ) + + def test_duration_format(self): + try: + from jsonschema._format import is_duration # noqa: F401 + except ImportError: # pragma: no cover + pass + else: + checker = FormatChecker() + self.assertTrue(checker.conforms(1, "duration")) + self.assertTrue(checker.conforms("P4Y", "duration")) + self.assertFalse(checker.conforms("test", "duration")) + + def test_uuid_format(self): + checker = FormatChecker() + self.assertTrue(checker.conforms(1, "uuid")) + self.assertTrue( + checker.conforms("6e6659ec-4503-4428-9f03-2e2ea4d6c278", "uuid"), + ) + self.assertFalse(checker.conforms("test", "uuid")) diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_jsonschema_test_suite.py python-jsonschema-4.6.0/jsonschema/tests/test_jsonschema_test_suite.py --- python-jsonschema-3.2.0/jsonschema/tests/test_jsonschema_test_suite.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_jsonschema_test_suite.py 2022-06-01 20:26:26.000000000 +0000 @@ -7,28 +7,31 @@ """ import sys -import warnings from jsonschema import ( Draft3Validator, Draft4Validator, Draft6Validator, Draft7Validator, + Draft201909Validator, + Draft202012Validator, draft3_format_checker, draft4_format_checker, draft6_format_checker, draft7_format_checker, + draft201909_format_checker, + draft202012_format_checker, ) from jsonschema.tests._helpers import bug from jsonschema.tests._suite import Suite -from jsonschema.validators import _DEPRECATED_DEFAULT_TYPES, create - SUITE = Suite() DRAFT3 = SUITE.version(name="draft3") DRAFT4 = SUITE.version(name="draft4") DRAFT6 = SUITE.version(name="draft6") DRAFT7 = SUITE.version(name="draft7") +DRAFT201909 = SUITE.version(name="draft2019-09") +DRAFT202012 = SUITE.version(name="draft2020-12") def skip(message, **kwargs): @@ -39,16 +42,44 @@ def missing_format(checker): - def missing_format(test): + def missing_format(test): # pragma: no cover schema = test.schema - if schema is True or schema is False or "format" not in schema: + if ( + schema is True + or schema is False + or "format" not in schema + or schema["format"] in checker.checkers + or test.valid + ): return - if schema["format"] not in checker.checkers: - return "Format checker {0!r} not found.".format(schema["format"]) + return "Format checker {0!r} not found.".format(schema["format"]) return missing_format +def complex_email_validation(test): + if test.subject != "email": + return + + message = "Complex email validation is (intentionally) unsupported." + return skip( + message=message, + description="an invalid domain", + )(test) or skip( + message=message, + description="an invalid IPv4-address-literal", + )(test) or skip( + message=message, + description="dot after local part is not valid", + )(test) or skip( + message=message, + description="dot before local part is not valid", + )(test) or skip( + message=message, + description="two subsequent dots inside local part are not valid", + )(test) + + is_narrow_build = sys.maxunicode == 2 ** 16 - 1 if is_narrow_build: # pragma: no cover message = "Not running surrogate Unicode case, this Python is narrow." @@ -56,7 +87,9 @@ def narrow_unicode_build(test): # pragma: no cover return skip( message=message, - description="one supplementary Unicode code point is not long enough", + description=( + "one supplementary Unicode code point is not long enough" + ), )(test) or skip( message=message, description="two supplementary Unicode code points is long enough", @@ -66,20 +99,83 @@ return +if sys.version_info < (3, 9): # pragma: no cover + message = "Rejecting leading zeros is 3.9+" + allowed_leading_zeros = skip( + message=message, + subject="ipv4", + description=( + "leading zeroes should be rejected, as they are treated as octals" + ), + ) +else: + def allowed_leading_zeros(test): # pragma: no cover + return + + +def leap_second(test): + message = "Leap seconds are unsupported." + return skip( + message=message, + subject="time", + description="a valid time string with leap second", + )(test) or skip( + message=message, + subject="time", + description="a valid time string with leap second, Zulu", + )(test) or skip( + message=message, + subject="time", + description="a valid time string with leap second with offset", + )(test) or skip( + message=message, + subject="time", + description="valid leap second, positive time-offset", + )(test) or skip( + message=message, + subject="time", + description="valid leap second, negative time-offset", + )(test) or skip( + message=message, + subject="time", + description="valid leap second, large positive time-offset", + )(test) or skip( + message=message, + subject="time", + description="valid leap second, large negative time-offset", + )(test) or skip( + message=message, + subject="time", + description="valid leap second, zero time-offset", + )(test) or skip( + message=message, + subject="date-time", + description="a valid date-time with a leap second, UTC", + )(test) or skip( + message=message, + subject="date-time", + description="a valid date-time with a leap second, with minus offset", + )(test) + + TestDraft3 = DRAFT3.to_unittest_testcase( DRAFT3.tests(), + DRAFT3.format_tests(), DRAFT3.optional_tests_of(name="bignum"), - DRAFT3.optional_tests_of(name="format"), + DRAFT3.optional_tests_of(name="non-bmp-regex"), DRAFT3.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft3Validator, format_checker=draft3_format_checker, skip=lambda test: ( narrow_unicode_build(test) or missing_format(draft3_format_checker)(test) + or complex_email_validation(test) or skip( - message="Upstream bug in strict_rfc3339", - subject="format", - description="case-insensitive T and Z", + message=bug(371), + subject="ref", + case_description=( + "$ref prevents a sibling id from changing the base uri" + ), )(test) ), ) @@ -87,14 +183,19 @@ TestDraft4 = DRAFT4.to_unittest_testcase( DRAFT4.tests(), + DRAFT4.format_tests(), DRAFT4.optional_tests_of(name="bignum"), - DRAFT4.optional_tests_of(name="format"), + DRAFT4.optional_tests_of(name="float-overflow"), + DRAFT4.optional_tests_of(name="non-bmp-regex"), DRAFT4.optional_tests_of(name="zeroTerminatedFloats"), Validator=Draft4Validator, format_checker=draft4_format_checker, skip=lambda test: ( narrow_unicode_build(test) + or allowed_leading_zeros(test) + or leap_second(test) or missing_format(draft4_format_checker)(test) + or complex_email_validation(test) or skip( message=bug(), subject="ref", @@ -103,21 +204,27 @@ or skip( message=bug(371), subject="ref", - case_description="Location-independent identifier", + case_description=( + "Location-independent identifier with " + "base URI change in subschema" + ), )(test) or skip( message=bug(371), subject="ref", case_description=( - "Location-independent identifier with absolute URI" + "$ref prevents a sibling id from changing the base uri" ), )(test) or skip( message=bug(371), - subject="ref", - case_description=( - "Location-independent identifier with base URI change in subschema" - ), + subject="id", + description="match $ref to id", + )(test) + or skip( + message=bug(371), + subject="id", + description="no match on enum or $ref to id", )(test) or skip( message=bug(), @@ -125,9 +232,12 @@ case_description="base URI change - change folder in subschema", )(test) or skip( - message="Upstream bug in strict_rfc3339", - subject="format", - description="case-insensitive T and Z", + message=bug(), + subject="ref", + case_description=( + "id must be resolved against nearest parent, " + "not just immediate parent" + ), )(test) ), ) @@ -135,48 +245,30 @@ TestDraft6 = DRAFT6.to_unittest_testcase( DRAFT6.tests(), + DRAFT6.format_tests(), DRAFT6.optional_tests_of(name="bignum"), - DRAFT6.optional_tests_of(name="format"), - DRAFT6.optional_tests_of(name="zeroTerminatedFloats"), + DRAFT6.optional_tests_of(name="float-overflow"), + DRAFT6.optional_tests_of(name="non-bmp-regex"), Validator=Draft6Validator, format_checker=draft6_format_checker, skip=lambda test: ( narrow_unicode_build(test) + or allowed_leading_zeros(test) + or leap_second(test) or missing_format(draft6_format_checker)(test) + or complex_email_validation(test) or skip( message=bug(), - subject="ref", - case_description="Recursive references between schemas", - )(test) - or skip( - message=bug(371), - subject="ref", - case_description="Location-independent identifier", - )(test) - or skip( - message=bug(371), - subject="ref", - case_description=( - "Location-independent identifier with absolute URI" - ), + subject="refRemote", + case_description="base URI change - change folder in subschema", )(test) or skip( message=bug(371), subject="ref", case_description=( - "Location-independent identifier with base URI change in subschema" + "$ref prevents a sibling $id from changing the base uri" ), )(test) - or skip( - message=bug(), - subject="refRemote", - case_description="base URI change - change folder in subschema", - )(test) - or skip( - message="Upstream bug in strict_rfc3339", - subject="format", - description="case-insensitive T and Z", - )(test) ), ) @@ -186,49 +278,40 @@ DRAFT7.format_tests(), DRAFT7.optional_tests_of(name="bignum"), DRAFT7.optional_tests_of(name="content"), - DRAFT7.optional_tests_of(name="zeroTerminatedFloats"), + DRAFT7.optional_tests_of(name="float-overflow"), + DRAFT7.optional_tests_of(name="non-bmp-regex"), Validator=Draft7Validator, format_checker=draft7_format_checker, skip=lambda test: ( narrow_unicode_build(test) + or allowed_leading_zeros(test) + or leap_second(test) or missing_format(draft7_format_checker)(test) + or complex_email_validation(test) or skip( message=bug(), - subject="ref", - case_description="Recursive references between schemas", - )(test) - or skip( - message=bug(371), - subject="ref", - case_description="Location-independent identifier", + subject="refRemote", + case_description="base URI change - change folder in subschema", )(test) or skip( message=bug(371), subject="ref", case_description=( - "Location-independent identifier with absolute URI" + "$ref prevents a sibling $id from changing the base uri" ), )(test) or skip( - message=bug(371), + message=bug(), subject="ref", case_description=( - "Location-independent identifier with base URI change in subschema" + "$id must be resolved against nearest parent, " + "not just immediate parent" ), )(test) or skip( - message=bug(), - subject="refRemote", - case_description="base URI change - change folder in subschema", - )(test) - or skip( - message="Upstream bug in strict_rfc3339", - subject="date-time", - description="case-insensitive T and Z", - )(test) - or skip( message=bug(593), subject="content", + valid=False, case_description=( "validation of string-encoded content based on media type" ), @@ -236,11 +319,13 @@ or skip( message=bug(593), subject="content", + valid=False, case_description="validation of binary string-encoding", )(test) or skip( message=bug(593), subject="content", + valid=False, case_description=( "validation of binary-encoded media type documents" ), @@ -249,29 +334,104 @@ ) -with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) +TestDraft201909 = DRAFT201909.to_unittest_testcase( + DRAFT201909.tests(), + DRAFT201909.optional_tests_of(name="bignum"), + DRAFT201909.optional_tests_of(name="float-overflow"), + DRAFT201909.optional_tests_of(name="non-bmp-regex"), + DRAFT201909.optional_tests_of(name="refOfUnknownKeyword"), + Validator=Draft201909Validator, + skip=lambda test: ( + skip( + message="unevaluatedItems is different in 2019-09 (needs work).", + subject="unevaluatedItems", + )(test) + or skip( + message="dynamicRef support isn't working yet.", + subject="recursiveRef", + )(test) + or skip( + message="These tests depends on dynamicRef working.", + subject="anchor", + case_description="same $anchor with different base uri", + )(test) + or skip( + message="Vocabulary support is not yet present.", + subject="vocabulary", + )(test) + or skip( + message=bug(), + subject="ref", + case_description=( + "$id must be resolved against nearest parent, " + "not just immediate parent" + ), + )(test) + ), +) - TestDraft3LegacyTypeCheck = DRAFT3.to_unittest_testcase( - # Interestingly the any part couldn't really be done w/the old API. - ( - (test for test in each if test.schema != {"type": "any"}) - for each in DRAFT3.tests_of(name="type") - ), - name="TestDraft3LegacyTypeCheck", - Validator=create( - meta_schema=Draft3Validator.META_SCHEMA, - validators=Draft3Validator.VALIDATORS, - default_types=_DEPRECATED_DEFAULT_TYPES, - ), - ) - TestDraft4LegacyTypeCheck = DRAFT4.to_unittest_testcase( - DRAFT4.tests_of(name="type"), - name="TestDraft4LegacyTypeCheck", - Validator=create( - meta_schema=Draft4Validator.META_SCHEMA, - validators=Draft4Validator.VALIDATORS, - default_types=_DEPRECATED_DEFAULT_TYPES, - ), - ) +TestDraft201909Format = DRAFT201909.to_unittest_testcase( + DRAFT201909.format_tests(), + Validator=Draft201909Validator, + format_checker=draft201909_format_checker, + skip=lambda test: ( + complex_email_validation(test) + or allowed_leading_zeros(test) + or leap_second(test) + or missing_format(draft201909_format_checker)(test) + or complex_email_validation(test) + ), +) + + +TestDraft202012 = DRAFT202012.to_unittest_testcase( + DRAFT202012.tests(), + DRAFT202012.optional_tests_of(name="bignum"), + DRAFT202012.optional_tests_of(name="float-overflow"), + DRAFT202012.optional_tests_of(name="non-bmp-regex"), + DRAFT202012.optional_tests_of(name="refOfUnknownKeyword"), + Validator=Draft202012Validator, + skip=lambda test: ( + narrow_unicode_build(test) + or skip( + message="dynamicRef support isn't working yet.", + subject="dynamicRef", + )(test) + or skip( + message="These tests depends on dynamicRef working.", + subject="defs", + )(test) + or skip( + message="These tests depends on dynamicRef working.", + subject="anchor", + case_description="same $anchor with different base uri", + )(test) + or skip( + message="Vocabulary support is not yet present.", + subject="vocabulary", + )(test) + or skip( + message=bug(), + subject="ref", + case_description=( + "$id must be resolved against nearest parent, " + "not just immediate parent" + ), + )(test) + ), +) + + +TestDraft202012Format = DRAFT202012.to_unittest_testcase( + DRAFT202012.format_tests(), + Validator=Draft202012Validator, + format_checker=draft202012_format_checker, + skip=lambda test: ( + complex_email_validation(test) + or allowed_leading_zeros(test) + or leap_second(test) + or missing_format(draft202012_format_checker)(test) + or complex_email_validation(test) + ), +) diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_types.py python-jsonschema-4.6.0/jsonschema/tests/test_types.py --- python-jsonschema-3.2.0/jsonschema/tests/test_types.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_types.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,15 +1,17 @@ """ -Tests on the new type interface. The actual correctness of the type checking -is handled in test_jsonschema_test_suite; these tests check that TypeChecker -functions correctly and can facilitate extensions to type checking +Tests for the `TypeChecker`-based type interface. + +The actual correctness of the type checking is handled in +`test_jsonschema_test_suite`; these tests check that TypeChecker +functions correctly at a more granular level. """ from collections import namedtuple from unittest import TestCase from jsonschema import ValidationError, _validators from jsonschema._types import TypeChecker -from jsonschema.exceptions import UndefinedTypeCheck -from jsonschema.validators import Draft4Validator, extend +from jsonschema.exceptions import UndefinedTypeCheck, UnknownType +from jsonschema.validators import Draft202012Validator, extend def equals_2(checker, instance): @@ -21,23 +23,11 @@ def is_object_or_named_tuple(checker, instance): - if Draft4Validator.TYPE_CHECKER.is_type(instance, "object"): + if Draft202012Validator.TYPE_CHECKER.is_type(instance, "object"): return True return is_namedtuple(instance) -def coerce_named_tuple(fn): - def coerced(validator, value, instance, schema): - if is_namedtuple(instance): - instance = instance._asdict() - return fn(validator, value, instance, schema) - return coerced - - -required = coerce_named_tuple(_validators.required) -properties = coerce_named_tuple(_validators.properties) - - class TestTypeChecker(TestCase): def test_is_type(self): checker = TypeChecker({"two": equals_2}) @@ -50,9 +40,16 @@ ) def test_is_unknown_type(self): - with self.assertRaises(UndefinedTypeCheck) as context: + with self.assertRaises(UndefinedTypeCheck) as e: TypeChecker().is_type(4, "foobar") - self.assertIn("foobar", str(context.exception)) + self.assertIn( + "'foobar' is unknown to this type checker", + str(e.exception), + ) + self.assertTrue( + e.exception.__suppress_context__, + msg="Expected the internal KeyError to be hidden.", + ) def test_checks_can_be_added_at_init(self): checker = TypeChecker({"two": equals_2}) @@ -121,8 +118,8 @@ return True CustomValidator = extend( - Draft4Validator, - type_checker=Draft4Validator.TYPE_CHECKER.redefine( + Draft202012Validator, + type_checker=Draft202012Validator.TYPE_CHECKER.redefine( "integer", int_or_str_int, ), ) @@ -134,16 +131,22 @@ with self.assertRaises(ValidationError): validator.validate(4.4) + with self.assertRaises(ValidationError): + validator.validate("foo") + def test_object_can_be_extended(self): schema = {"type": "object"} Point = namedtuple("Point", ["x", "y"]) - type_checker = Draft4Validator.TYPE_CHECKER.redefine( - u"object", is_object_or_named_tuple, + type_checker = Draft202012Validator.TYPE_CHECKER.redefine( + "object", is_object_or_named_tuple, ) - CustomValidator = extend(Draft4Validator, type_checker=type_checker) + CustomValidator = extend( + Draft202012Validator, + type_checker=type_checker, + ) validator = CustomValidator(schema) validator.validate(Point(x=4, y=5)) @@ -151,11 +154,14 @@ def test_object_extensions_require_custom_validators(self): schema = {"type": "object", "required": ["x"]} - type_checker = Draft4Validator.TYPE_CHECKER.redefine( - u"object", is_object_or_named_tuple, + type_checker = Draft202012Validator.TYPE_CHECKER.redefine( + "object", is_object_or_named_tuple, ) - CustomValidator = extend(Draft4Validator, type_checker=type_checker) + CustomValidator = extend( + Draft202012Validator, + type_checker=type_checker, + ) validator = CustomValidator(schema) Point = namedtuple("Point", ["x", "y"]) @@ -170,12 +176,22 @@ "properties": {"x": {"type": "integer"}}, } - type_checker = Draft4Validator.TYPE_CHECKER.redefine( - u"object", is_object_or_named_tuple, + type_checker = Draft202012Validator.TYPE_CHECKER.redefine( + "object", is_object_or_named_tuple, ) + def coerce_named_tuple(fn): + def coerced(validator, value, instance, schema): + if is_namedtuple(instance): + instance = instance._asdict() + return fn(validator, value, instance, schema) + return coerced + + required = coerce_named_tuple(_validators.required) + properties = coerce_named_tuple(_validators.properties) + CustomValidator = extend( - Draft4Validator, + Draft202012Validator, type_checker=type_checker, validators={"required": required, "properties": properties}, ) @@ -188,3 +204,14 @@ with self.assertRaises(ValidationError): validator.validate(Point(x="not an integer", y=5)) + + # As well as still handle objects. + validator.validate({"x": 4, "y": 5}) + + with self.assertRaises(ValidationError): + validator.validate({"x": "not an integer", "y": 5}) + + def test_unknown_type(self): + with self.assertRaises(UnknownType) as e: + Draft202012Validator({}).is_type(12, "some unknown type") + self.assertIn("'some unknown type'", str(e.exception)) diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_utils.py python-jsonschema-4.6.0/jsonschema/tests/test_utils.py --- python-jsonschema-3.2.0/jsonschema/tests/test_utils.py 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_utils.py 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,124 @@ +from unittest import TestCase + +from jsonschema._utils import equal + + +class TestEqual(TestCase): + def test_none(self): + self.assertTrue(equal(None, None)) + + +class TestDictEqual(TestCase): + def test_equal_dictionaries(self): + dict_1 = {"a": "b", "c": "d"} + dict_2 = {"c": "d", "a": "b"} + self.assertTrue(equal(dict_1, dict_2)) + + def test_missing_key(self): + dict_1 = {"a": "b", "c": "d"} + dict_2 = {"c": "d", "x": "b"} + self.assertFalse(equal(dict_1, dict_2)) + + def test_additional_key(self): + dict_1 = {"a": "b", "c": "d"} + dict_2 = {"c": "d", "a": "b", "x": "x"} + self.assertFalse(equal(dict_1, dict_2)) + + def test_missing_value(self): + dict_1 = {"a": "b", "c": "d"} + dict_2 = {"c": "d", "a": "x"} + self.assertFalse(equal(dict_1, dict_2)) + + def test_empty_dictionaries(self): + dict_1 = {} + dict_2 = {} + self.assertTrue(equal(dict_1, dict_2)) + + def test_one_none(self): + dict_1 = None + dict_2 = {"a": "b", "c": "d"} + self.assertFalse(equal(dict_1, dict_2)) + + def test_same_item(self): + dict_1 = {"a": "b", "c": "d"} + self.assertTrue(equal(dict_1, dict_1)) + + def test_nested_equal(self): + dict_1 = {"a": {"a": "b", "c": "d"}, "c": "d"} + dict_2 = {"c": "d", "a": {"a": "b", "c": "d"}} + self.assertTrue(equal(dict_1, dict_2)) + + def test_nested_dict_unequal(self): + dict_1 = {"a": {"a": "b", "c": "d"}, "c": "d"} + dict_2 = {"c": "d", "a": {"a": "b", "c": "x"}} + self.assertFalse(equal(dict_1, dict_2)) + + def test_mixed_nested_equal(self): + dict_1 = {"a": ["a", "b", "c", "d"], "c": "d"} + dict_2 = {"c": "d", "a": ["a", "b", "c", "d"]} + self.assertTrue(equal(dict_1, dict_2)) + + def test_nested_list_unequal(self): + dict_1 = {"a": ["a", "b", "c", "d"], "c": "d"} + dict_2 = {"c": "d", "a": ["b", "c", "d", "a"]} + self.assertFalse(equal(dict_1, dict_2)) + + +class TestListEqual(TestCase): + def test_equal_lists(self): + list_1 = ["a", "b", "c"] + list_2 = ["a", "b", "c"] + self.assertTrue(equal(list_1, list_2)) + + def test_unsorted_lists(self): + list_1 = ["a", "b", "c"] + list_2 = ["b", "b", "a"] + self.assertFalse(equal(list_1, list_2)) + + def test_first_list_larger(self): + list_1 = ["a", "b", "c"] + list_2 = ["a", "b"] + self.assertFalse(equal(list_1, list_2)) + + def test_second_list_larger(self): + list_1 = ["a", "b"] + list_2 = ["a", "b", "c"] + self.assertFalse(equal(list_1, list_2)) + + def test_list_with_none_unequal(self): + list_1 = ["a", "b", None] + list_2 = ["a", "b", "c"] + self.assertFalse(equal(list_1, list_2)) + + list_1 = ["a", "b", None] + list_2 = [None, "b", "c"] + self.assertFalse(equal(list_1, list_2)) + + def test_list_with_none_equal(self): + list_1 = ["a", None, "c"] + list_2 = ["a", None, "c"] + self.assertTrue(equal(list_1, list_2)) + + def test_empty_list(self): + list_1 = [] + list_2 = [] + self.assertTrue(equal(list_1, list_2)) + + def test_one_none(self): + list_1 = None + list_2 = [] + self.assertFalse(equal(list_1, list_2)) + + def test_same_list(self): + list_1 = ["a", "b", "c"] + self.assertTrue(equal(list_1, list_1)) + + def test_equal_nested_lists(self): + list_1 = ["a", ["b", "c"], "d"] + list_2 = ["a", ["b", "c"], "d"] + self.assertTrue(equal(list_1, list_2)) + + def test_unequal_nested_lists(self): + list_1 = ["a", ["b", "c"], "d"] + list_2 = ["a", [], "c"] + self.assertFalse(equal(list_1, list_2)) diff -Nru python-jsonschema-3.2.0/jsonschema/tests/test_validators.py python-jsonschema-4.6.0/jsonschema/tests/test_validators.py --- python-jsonschema-3.2.0/jsonschema/tests/test_validators.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/tests/test_validators.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,37 +1,46 @@ -from collections import deque +from __future__ import annotations + +from collections import deque, namedtuple from contextlib import contextmanager from decimal import Decimal from io import BytesIO -from unittest import TestCase +from unittest import TestCase, mock +from urllib.request import pathname2url import json import os import sys import tempfile import unittest +import warnings -from twisted.trial.unittest import SynchronousTestCase import attr -from jsonschema import FormatChecker, TypeChecker, exceptions, validators -from jsonschema.compat import PY3, pathname2url +from jsonschema import ( + FormatChecker, + TypeChecker, + exceptions, + protocols, + validators, +) from jsonschema.tests._helpers import bug -def startswith(validator, startswith, instance, schema): - if not instance.startswith(startswith): - yield exceptions.ValidationError(u"Whoops!") +def fail(validator, errors, instance, schema): + for each in errors: + each.setdefault("message", "You told me to fail!") + yield exceptions.ValidationError(**each) -class TestCreateAndExtend(SynchronousTestCase): +class TestCreateAndExtend(TestCase): def setUp(self): self.addCleanup( self.assertEqual, - validators.meta_schemas, - dict(validators.meta_schemas), + validators._META_SCHEMAS, + dict(validators._META_SCHEMAS), ) - self.meta_schema = {u"$id": "some://meta/schema"} - self.validators = {u"startswith": startswith} + self.meta_schema = {"$id": "some://meta/schema"} + self.validators = {"fail": fail} self.type_checker = TypeChecker() self.Validator = validators.create( meta_schema=self.meta_schema, @@ -53,66 +62,123 @@ ) def test_init(self): - schema = {u"startswith": u"foo"} + schema = {"fail": []} self.assertEqual(self.Validator(schema).schema, schema) - def test_iter_errors(self): - schema = {u"startswith": u"hel"} - iter_errors = self.Validator(schema).iter_errors + def test_iter_errors_successful(self): + schema = {"fail": []} + validator = self.Validator(schema) - errors = list(iter_errors(u"hello")) + errors = list(validator.iter_errors("hello")) self.assertEqual(errors, []) + def test_iter_errors_one_error(self): + schema = {"fail": [{"message": "Whoops!"}]} + validator = self.Validator(schema) + expected_error = exceptions.ValidationError( - u"Whoops!", - instance=u"goodbye", + "Whoops!", + instance="goodbye", schema=schema, - validator=u"startswith", - validator_value=u"hel", - schema_path=deque([u"startswith"]), + validator="fail", + validator_value=[{"message": "Whoops!"}], + schema_path=deque(["fail"]), ) - errors = list(iter_errors(u"goodbye")) + errors = list(validator.iter_errors("goodbye")) self.assertEqual(len(errors), 1) self.assertEqual(errors[0]._contents(), expected_error._contents()) + def test_iter_errors_multiple_errors(self): + schema = { + "fail": [ + {"message": "First"}, + {"message": "Second!", "validator": "asdf"}, + {"message": "Third"}, + ], + } + validator = self.Validator(schema) + + errors = list(validator.iter_errors("goodbye")) + self.assertEqual(len(errors), 3) + def test_if_a_version_is_provided_it_is_registered(self): Validator = validators.create( - meta_schema={u"$id": "something"}, + meta_schema={"$id": "something"}, version="my version", ) - self.addCleanup(validators.meta_schemas.pop, "something") + self.addCleanup(validators._META_SCHEMAS.pop, "something") self.assertEqual(Validator.__name__, "MyVersionValidator") + self.assertEqual(Validator.__qualname__, "MyVersionValidator") + + def test_repr(self): + Validator = validators.create( + meta_schema={"$id": "something"}, + version="my version", + ) + self.addCleanup(validators._META_SCHEMAS.pop, "something") + self.assertEqual( + repr(Validator({})), + "MyVersionValidator(schema={}, format_checker=None)", + ) + + def test_long_repr(self): + Validator = validators.create( + meta_schema={"$id": "something"}, + version="my version", + ) + self.addCleanup(validators._META_SCHEMAS.pop, "something") + self.assertEqual( + repr(Validator({"a": list(range(1000))})), ( + "MyVersionValidator(schema={'a': [0, 1, 2, 3, 4, 5, ...]}, " + "format_checker=None)" + ), + ) + + def test_repr_no_version(self): + Validator = validators.create(meta_schema={}) + self.assertEqual( + repr(Validator({})), + "Validator(schema={}, format_checker=None)", + ) + + def test_dashes_are_stripped_from_validator_names(self): + Validator = validators.create( + meta_schema={"$id": "something"}, + version="foo-bar", + ) + self.addCleanup(validators._META_SCHEMAS.pop, "something") + self.assertEqual(Validator.__qualname__, "FooBarValidator") def test_if_a_version_is_not_provided_it_is_not_registered(self): - original = dict(validators.meta_schemas) - validators.create(meta_schema={u"id": "id"}) - self.assertEqual(validators.meta_schemas, original) + original = dict(validators._META_SCHEMAS) + validators.create(meta_schema={"id": "id"}) + self.assertEqual(validators._META_SCHEMAS, original) def test_validates_registers_meta_schema_id(self): meta_schema_key = "meta schema id" - my_meta_schema = {u"id": meta_schema_key} + my_meta_schema = {"id": meta_schema_key} validators.create( meta_schema=my_meta_schema, version="my version", id_of=lambda s: s.get("id", ""), ) - self.addCleanup(validators.meta_schemas.pop, meta_schema_key) + self.addCleanup(validators._META_SCHEMAS.pop, meta_schema_key) - self.assertIn(meta_schema_key, validators.meta_schemas) + self.assertIn(meta_schema_key, validators._META_SCHEMAS) def test_validates_registers_meta_schema_draft6_id(self): meta_schema_key = "meta schema $id" - my_meta_schema = {u"$id": meta_schema_key} + my_meta_schema = {"$id": meta_schema_key} validators.create( meta_schema=my_meta_schema, version="my version", ) - self.addCleanup(validators.meta_schemas.pop, meta_schema_key) + self.addCleanup(validators._META_SCHEMAS.pop, meta_schema_key) - self.assertIn(meta_schema_key, validators.meta_schemas) + self.assertIn(meta_schema_key, validators._META_SCHEMAS) def test_create_default_types(self): Validator = validators.create(meta_schema={}, validators=()) @@ -120,13 +186,13 @@ all( Validator({}).is_type(instance=instance, type=type) for type, instance in [ - (u"array", []), - (u"boolean", True), - (u"integer", 12), - (u"null", None), - (u"number", 12.0), - (u"object", {}), - (u"string", u"foo"), + ("array", []), + ("boolean", True), + ("integer", 12), + ("null", None), + ("number", 12.0), + ("object", {}), + ("string", "foo"), ] ), ) @@ -137,7 +203,7 @@ Extended = validators.extend( self.Validator, - validators={u"new": new}, + validators={"new": new}, ) self.assertEqual( ( @@ -158,11 +224,11 @@ Extending a validator preserves its notion of schema IDs. """ def id_of(schema): - return schema.get(u"__test__", self.Validator.ID_OF(schema)) + return schema.get("__test__", self.Validator.ID_OF(schema)) correct_id = "the://correct/id/" meta_schema = { - u"$id": "the://wrong/id/", - u"__test__": correct_id, + "$id": "the://wrong/id/", + "__test__": correct_id, } Original = validators.create( meta_schema=meta_schema, @@ -176,289 +242,53 @@ self.assertEqual(Derived.ID_OF(Derived.META_SCHEMA), correct_id) -class TestLegacyTypeChecking(SynchronousTestCase): - def test_create_default_types(self): - Validator = validators.create(meta_schema={}, validators=()) - self.assertEqual( - set(Validator.DEFAULT_TYPES), { - u"array", - u"boolean", - u"integer", - u"null", - u"number", - u"object", u"string", - }, - ) - self.flushWarnings() - - def test_extend(self): - Validator = validators.create(meta_schema={}, validators=()) - original = dict(Validator.VALIDATORS) - new = object() - - Extended = validators.extend( - Validator, - validators={u"new": new}, - ) - self.assertEqual( - ( - Extended.VALIDATORS, - Extended.META_SCHEMA, - Extended.TYPE_CHECKER, - Validator.VALIDATORS, - - Extended.DEFAULT_TYPES, - Extended({}).DEFAULT_TYPES, - self.flushWarnings()[0]["message"], - ), ( - dict(original, new=new), - Validator.META_SCHEMA, - Validator.TYPE_CHECKER, - original, - - Validator.DEFAULT_TYPES, - Validator.DEFAULT_TYPES, - self.flushWarnings()[0]["message"], - ), - ) - - def test_types_redefines_the_validators_type_checker(self): - schema = {"type": "string"} - self.assertFalse(validators.Draft7Validator(schema).is_valid(12)) - - validator = validators.Draft7Validator( - schema, - types={"string": (str, int)}, - ) - self.assertTrue(validator.is_valid(12)) - self.flushWarnings() - - def test_providing_default_types_warns(self): - self.assertWarns( - category=DeprecationWarning, - message=( - "The default_types argument is deprecated. " - "Use the type_checker argument instead." - ), - # https://tm.tl/9363 :'( - filename=sys.modules[self.assertWarns.__module__].__file__, - - f=validators.create, - meta_schema={}, - validators={}, - default_types={"foo": object}, - ) - - def test_cannot_ask_for_default_types_with_non_default_type_checker(self): - """ - We raise an error when you ask a validator with non-default - type checker for its DEFAULT_TYPES. - - The type checker argument is new, so no one but this library - itself should be trying to use it, and doing so while then - asking for DEFAULT_TYPES makes no sense (not to mention is - deprecated), since type checkers are not strictly about Python - type. - """ - Validator = validators.create( - meta_schema={}, - validators={}, - type_checker=TypeChecker(), - ) - with self.assertRaises(validators._DontDoThat) as e: - Validator.DEFAULT_TYPES - - self.assertIn( - "DEFAULT_TYPES cannot be used on Validators using TypeCheckers", - str(e.exception), - ) - with self.assertRaises(validators._DontDoThat): - Validator({}).DEFAULT_TYPES - - self.assertFalse(self.flushWarnings()) - - def test_providing_explicit_type_checker_does_not_warn(self): - Validator = validators.create( - meta_schema={}, - validators={}, - type_checker=TypeChecker(), - ) - self.assertFalse(self.flushWarnings()) - - Validator({}) - self.assertFalse(self.flushWarnings()) - - def test_providing_neither_does_not_warn(self): - Validator = validators.create(meta_schema={}, validators={}) - self.assertFalse(self.flushWarnings()) - - Validator({}) - self.assertFalse(self.flushWarnings()) - - def test_providing_default_types_with_type_checker_errors(self): - with self.assertRaises(TypeError) as e: - validators.create( - meta_schema={}, - validators={}, - default_types={"foo": object}, - type_checker=TypeChecker(), - ) - - self.assertIn( - "Do not specify default_types when providing a type checker", - str(e.exception), - ) - self.assertFalse(self.flushWarnings()) - - def test_extending_a_legacy_validator_with_a_type_checker_errors(self): - Validator = validators.create( - meta_schema={}, - validators={}, - default_types={u"array": list} - ) - with self.assertRaises(TypeError) as e: - validators.extend( - Validator, - validators={}, - type_checker=TypeChecker(), - ) - - self.assertIn( - ( - "Cannot extend a validator created with default_types " - "with a type_checker. Update the validator to use a " - "type_checker when created." - ), - str(e.exception), - ) - self.flushWarnings() - - def test_extending_a_legacy_validator_does_not_rewarn(self): - Validator = validators.create(meta_schema={}, default_types={}) - self.assertTrue(self.flushWarnings()) - - validators.extend(Validator) - self.assertFalse(self.flushWarnings()) - - def test_accessing_default_types_warns(self): - Validator = validators.create(meta_schema={}, validators={}) - self.assertFalse(self.flushWarnings()) - - self.assertWarns( - DeprecationWarning, - ( - "The DEFAULT_TYPES attribute is deprecated. " - "See the type checker attached to this validator instead." - ), - # https://tm.tl/9363 :'( - sys.modules[self.assertWarns.__module__].__file__, - - getattr, - Validator, - "DEFAULT_TYPES", - ) - - def test_accessing_default_types_on_the_instance_warns(self): - Validator = validators.create(meta_schema={}, validators={}) - self.assertFalse(self.flushWarnings()) - - self.assertWarns( - DeprecationWarning, - ( - "The DEFAULT_TYPES attribute is deprecated. " - "See the type checker attached to this validator instead." - ), - # https://tm.tl/9363 :'( - sys.modules[self.assertWarns.__module__].__file__, - - getattr, - Validator({}), - "DEFAULT_TYPES", - ) - - def test_providing_types_to_init_warns(self): - Validator = validators.create(meta_schema={}, validators={}) - self.assertFalse(self.flushWarnings()) - - self.assertWarns( - category=DeprecationWarning, - message=( - "The types argument is deprecated. " - "Provide a type_checker to jsonschema.validators.extend " - "instead." - ), - # https://tm.tl/9363 :'( - filename=sys.modules[self.assertWarns.__module__].__file__, - - f=Validator, - schema={}, - types={"bar": object}, - ) - - -class TestIterErrors(TestCase): - def setUp(self): - self.validator = validators.Draft3Validator({}) - - def test_iter_errors(self): - instance = [1, 2] - schema = { - u"disallow": u"array", - u"enum": [["a", "b", "c"], ["d", "e", "f"]], - u"minItems": 3, - } - - got = (e.message for e in self.validator.iter_errors(instance, schema)) - expected = [ - "%r is disallowed for [1, 2]" % (schema["disallow"],), - "[1, 2] is too short", - "[1, 2] is not one of %r" % (schema["enum"],), - ] - self.assertEqual(sorted(got), sorted(expected)) - - def test_iter_errors_multiple_failures_one_validator(self): - instance = {"foo": 2, "bar": [1], "baz": 15, "quux": "spam"} - schema = { - u"properties": { - "foo": {u"type": "string"}, - "bar": {u"minItems": 2}, - "baz": {u"maximum": 10, u"enum": [2, 4, 6, 8]}, - }, - } - - errors = list(self.validator.iter_errors(instance, schema)) - self.assertEqual(len(errors), 4) - - class TestValidationErrorMessages(TestCase): def message_for(self, instance, schema, *args, **kwargs): - kwargs.setdefault("cls", validators.Draft3Validator) - with self.assertRaises(exceptions.ValidationError) as e: - validators.validate(instance, schema, *args, **kwargs) - return e.exception.message + cls = kwargs.pop("cls", validators._LATEST_VERSION) + cls.check_schema(schema) + validator = cls(schema, *args, **kwargs) + errors = list(validator.iter_errors(instance)) + self.assertTrue(errors, msg=f"No errors were raised for {instance!r}") + self.assertEqual( + len(errors), + 1, + msg=f"Expected exactly one error, found {errors!r}", + ) + return errors[0].message def test_single_type_failure(self): - message = self.message_for(instance=1, schema={u"type": u"string"}) - self.assertEqual(message, "1 is not of type %r" % u"string") + message = self.message_for(instance=1, schema={"type": "string"}) + self.assertEqual(message, "1 is not of type 'string'") def test_single_type_list_failure(self): - message = self.message_for(instance=1, schema={u"type": [u"string"]}) - self.assertEqual(message, "1 is not of type %r" % u"string") + message = self.message_for(instance=1, schema={"type": ["string"]}) + self.assertEqual(message, "1 is not of type 'string'") def test_multiple_type_failure(self): - types = u"string", u"object" - message = self.message_for(instance=1, schema={u"type": list(types)}) - self.assertEqual(message, "1 is not of type %r, %r" % types) + types = "string", "object" + message = self.message_for(instance=1, schema={"type": list(types)}) + self.assertEqual(message, "1 is not of type 'string', 'object'") def test_object_without_title_type_failure(self): - type = {u"type": [{u"minimum": 3}]} - message = self.message_for(instance=1, schema={u"type": [type]}) - self.assertEqual(message, "1 is less than the minimum of 3") + type = {"type": [{"minimum": 3}]} + message = self.message_for( + instance=1, + schema={"type": [type]}, + cls=validators.Draft3Validator, + ) + self.assertEqual( + message, + "1 is not of type {'type': [{'minimum': 3}]}", + ) def test_object_with_named_type_failure(self): - schema = {u"type": [{u"name": "Foo", u"minimum": 3}]} - message = self.message_for(instance=1, schema=schema) - self.assertEqual(message, "1 is less than the minimum of 3") + schema = {"type": [{"name": "Foo", "minimum": 3}]} + message = self.message_for( + instance=1, + schema=schema, + cls=validators.Draft3Validator, + ) + self.assertEqual(message, "1 is not of type 'Foo'") def test_minimum(self): message = self.message_for(instance=1, schema={"minimum": 2}) @@ -470,56 +300,58 @@ def test_dependencies_single_element(self): depend, on = "bar", "foo" - schema = {u"dependencies": {depend: on}} + schema = {"dependencies": {depend: on}} message = self.message_for( instance={"bar": 2}, schema=schema, cls=validators.Draft3Validator, ) - self.assertEqual(message, "%r is a dependency of %r" % (on, depend)) + self.assertEqual(message, "'foo' is a dependency of 'bar'") def test_dependencies_list_draft3(self): depend, on = "bar", "foo" - schema = {u"dependencies": {depend: [on]}} + schema = {"dependencies": {depend: [on]}} message = self.message_for( instance={"bar": 2}, schema=schema, cls=validators.Draft3Validator, ) - self.assertEqual(message, "%r is a dependency of %r" % (on, depend)) + self.assertEqual(message, "'foo' is a dependency of 'bar'") def test_dependencies_list_draft7(self): depend, on = "bar", "foo" - schema = {u"dependencies": {depend: [on]}} + schema = {"dependencies": {depend: [on]}} message = self.message_for( instance={"bar": 2}, schema=schema, cls=validators.Draft7Validator, ) - self.assertEqual(message, "%r is a dependency of %r" % (on, depend)) + self.assertEqual(message, "'foo' is a dependency of 'bar'") def test_additionalItems_single_failure(self): message = self.message_for( instance=[2], - schema={u"items": [], u"additionalItems": False}, + schema={"items": [], "additionalItems": False}, + cls=validators.Draft3Validator, ) self.assertIn("(2 was unexpected)", message) def test_additionalItems_multiple_failures(self): message = self.message_for( instance=[1, 2, 3], - schema={u"items": [], u"additionalItems": False} + schema={"items": [], "additionalItems": False}, + cls=validators.Draft3Validator, ) self.assertIn("(1, 2, 3 were unexpected)", message) def test_additionalProperties_single_failure(self): additional = "foo" - schema = {u"additionalProperties": False} + schema = {"additionalProperties": False} message = self.message_for(instance={additional: 2}, schema=schema) - self.assertIn("(%r was unexpected)" % (additional,), message) + self.assertIn("('foo' was unexpected)", message) def test_additionalProperties_multiple_failures(self): - schema = {u"additionalProperties": False} + schema = {"additionalProperties": False} message = self.message_for( instance=dict.fromkeys(["foo", "bar"]), schema=schema, @@ -530,31 +362,30 @@ self.assertIn("were unexpected)", message) def test_const(self): - schema = {u"const": 12} + schema = {"const": 12} message = self.message_for( instance={"foo": "bar"}, schema=schema, - cls=validators.Draft6Validator, ) self.assertIn("12 was expected", message) - def test_contains(self): - schema = {u"contains": {u"const": 12}} + def test_contains_draft_6(self): + schema = {"contains": {"const": 12}} message = self.message_for( instance=[2, {}, []], schema=schema, cls=validators.Draft6Validator, ) - self.assertIn( - "None of [2, {}, []] are valid under the given schema", + self.assertEqual( message, + "None of [2, {}, []] are valid under the given schema", ) def test_invalid_format_default_message(self): checker = FormatChecker(formats=()) - checker.checks(u"thing")(lambda value: False) + checker.checks("thing")(lambda value: False) - schema = {u"format": u"thing"} + schema = {"format": "thing"} message = self.message_for( instance="bla", schema=schema, @@ -566,32 +397,32 @@ self.assertIn("is not a", message) def test_additionalProperties_false_patternProperties(self): - schema = {u"type": u"object", - u"additionalProperties": False, - u"patternProperties": { - u"^abc$": {u"type": u"string"}, - u"^def$": {u"type": u"string"}, + schema = {"type": "object", + "additionalProperties": False, + "patternProperties": { + "^abc$": {"type": "string"}, + "^def$": {"type": "string"}, }} message = self.message_for( - instance={u"zebra": 123}, + instance={"zebra": 123}, schema=schema, cls=validators.Draft4Validator, ) self.assertEqual( message, "{} does not match any of the regexes: {}, {}".format( - repr(u"zebra"), repr(u"^abc$"), repr(u"^def$"), + repr("zebra"), repr("^abc$"), repr("^def$"), ), ) message = self.message_for( - instance={u"zebra": 123, u"fish": 456}, + instance={"zebra": 123, "fish": 456}, schema=schema, cls=validators.Draft4Validator, ) self.assertEqual( message, "{}, {} do not match any of the regexes: {}, {}".format( - repr(u"fish"), repr(u"zebra"), repr(u"^abc$"), repr(u"^def$") + repr("fish"), repr("zebra"), repr("^abc$"), repr("^def$"), ), ) @@ -599,9 +430,197 @@ message = self.message_for( instance="something", schema=False, - cls=validators.Draft7Validator, ) - self.assertIn("False schema does not allow 'something'", message) + self.assertEqual(message, "False schema does not allow 'something'") + + def test_multipleOf(self): + message = self.message_for( + instance=3, + schema={"multipleOf": 2}, + ) + self.assertEqual(message, "3 is not a multiple of 2") + + def test_minItems(self): + message = self.message_for(instance=[], schema={"minItems": 2}) + self.assertEqual(message, "[] is too short") + + def test_maxItems(self): + message = self.message_for(instance=[1, 2, 3], schema={"maxItems": 2}) + self.assertEqual(message, "[1, 2, 3] is too long") + + def test_prefixItems_with_items(self): + message = self.message_for( + instance=[1, 2, "foo", 5], + schema={"items": False, "prefixItems": [{}, {}]}, + ) + self.assertEqual(message, "Expected at most 2 items, but found 4") + + def test_minLength(self): + message = self.message_for( + instance="", + schema={"minLength": 2}, + ) + self.assertEqual(message, "'' is too short") + + def test_maxLength(self): + message = self.message_for( + instance="abc", + schema={"maxLength": 2}, + ) + self.assertEqual(message, "'abc' is too long") + + def test_pattern(self): + message = self.message_for( + instance="bbb", + schema={"pattern": "^a*$"}, + ) + self.assertEqual(message, "'bbb' does not match '^a*$'") + + def test_does_not_contain(self): + message = self.message_for( + instance=[], + schema={"contains": {"type": "string"}}, + ) + self.assertEqual( + message, + "[] does not contain items matching the given schema", + ) + + def test_contains_too_few(self): + message = self.message_for( + instance=["foo", 1], + schema={"contains": {"type": "string"}, "minContains": 2}, + ) + self.assertEqual( + message, + "Too few items match the given schema " + "(expected at least 2 but only 1 matched)", + ) + + def test_contains_too_few_both_constrained(self): + message = self.message_for( + instance=["foo", 1], + schema={ + "contains": {"type": "string"}, + "minContains": 2, + "maxContains": 4, + }, + ) + self.assertEqual( + message, + "Too few items match the given schema (expected at least 2 but " + "only 1 matched)", + ) + + def test_contains_too_many(self): + message = self.message_for( + instance=["foo", "bar", "baz"], + schema={"contains": {"type": "string"}, "maxContains": 2}, + ) + self.assertEqual( + message, + "Too many items match the given schema (expected at most 2)", + ) + + def test_contains_too_many_both_constrained(self): + message = self.message_for( + instance=["foo"] * 5, + schema={ + "contains": {"type": "string"}, + "minContains": 2, + "maxContains": 4, + }, + ) + self.assertEqual( + message, + "Too many items match the given schema (expected at most 4)", + ) + + def test_exclusiveMinimum(self): + message = self.message_for( + instance=3, + schema={"exclusiveMinimum": 5}, + ) + self.assertEqual( + message, + "3 is less than or equal to the minimum of 5", + ) + + def test_exclusiveMaximum(self): + message = self.message_for(instance=3, schema={"exclusiveMaximum": 2}) + self.assertEqual( + message, + "3 is greater than or equal to the maximum of 2", + ) + + def test_required(self): + message = self.message_for(instance={}, schema={"required": ["foo"]}) + self.assertEqual(message, "'foo' is a required property") + + def test_dependentRequired(self): + message = self.message_for( + instance={"foo": {}}, + schema={"dependentRequired": {"foo": ["bar"]}}, + ) + self.assertEqual(message, "'bar' is a dependency of 'foo'") + + def test_minProperties(self): + message = self.message_for(instance={}, schema={"minProperties": 2}) + self.assertEqual(message, "{} does not have enough properties") + + def test_maxProperties(self): + message = self.message_for( + instance={"a": {}, "b": {}, "c": {}}, + schema={"maxProperties": 2}, + ) + self.assertEqual( + message, + "{'a': {}, 'b': {}, 'c': {}} has too many properties", + ) + + def test_oneOf_matches_none(self): + message = self.message_for(instance={}, schema={"oneOf": [False]}) + self.assertEqual( + message, + "{} is not valid under any of the given schemas", + ) + + def test_oneOf_matches_too_many(self): + message = self.message_for(instance={}, schema={"oneOf": [True, True]}) + self.assertEqual(message, "{} is valid under each of True, True") + + def test_unevaluated_items(self): + schema = {"type": "array", "unevaluatedItems": False} + message = self.message_for(instance=["foo", "bar"], schema=schema) + self.assertIn( + message, + "Unevaluated items are not allowed ('bar', 'foo' were unexpected)", + ) + + def test_unevaluated_items_on_invalid_type(self): + schema = {"type": "array", "unevaluatedItems": False} + message = self.message_for(instance="foo", schema=schema) + self.assertEqual(message, "'foo' is not of type 'array'") + + def test_unevaluated_properties(self): + schema = {"type": "object", "unevaluatedProperties": False} + message = self.message_for( + instance={ + "foo": "foo", + "bar": "bar", + }, + schema=schema, + ) + self.assertEqual( + message, + "Unevaluated properties are not allowed " + "('bar', 'foo' were unexpected)", + ) + + def test_unevaluated_properties_on_invalid_type(self): + schema = {"type": "object", "unevaluatedProperties": False} + message = self.message_for(instance="foo", schema=schema) + self.assertEqual(message, "'foo' is not of type 'object'") class TestValidationErrorDetails(TestCase): @@ -630,6 +649,7 @@ self.assertEqual(e.path, deque([])) self.assertEqual(e.relative_path, deque([])) self.assertEqual(e.absolute_path, deque([])) + self.assertEqual(e.json_path, "$") self.assertEqual(e.schema_path, deque(["anyOf"])) self.assertEqual(e.relative_schema_path, deque(["anyOf"])) @@ -648,6 +668,7 @@ self.assertEqual(e1.path, deque([])) self.assertEqual(e1.absolute_path, deque([])) self.assertEqual(e1.relative_path, deque([])) + self.assertEqual(e1.json_path, "$") self.assertEqual(e1.schema_path, deque([0, "minimum"])) self.assertEqual(e1.relative_schema_path, deque([0, "minimum"])) @@ -666,6 +687,7 @@ self.assertEqual(e2.path, deque([])) self.assertEqual(e2.relative_path, deque([])) self.assertEqual(e2.absolute_path, deque([])) + self.assertEqual(e2.json_path, "$") self.assertEqual(e2.schema_path, deque([1, "type"])) self.assertEqual(e2.relative_schema_path, deque([1, "type"])) @@ -699,6 +721,7 @@ self.assertEqual(e.path, deque([])) self.assertEqual(e.relative_path, deque([])) self.assertEqual(e.absolute_path, deque([])) + self.assertEqual(e.json_path, "$") self.assertEqual(e.schema_path, deque(["type"])) self.assertEqual(e.relative_schema_path, deque(["type"])) @@ -717,6 +740,7 @@ self.assertEqual(e1.path, deque([])) self.assertEqual(e1.relative_path, deque([])) self.assertEqual(e1.absolute_path, deque([])) + self.assertEqual(e1.json_path, "$") self.assertEqual(e1.schema_path, deque([0, "type"])) self.assertEqual(e1.relative_schema_path, deque([0, "type"])) @@ -727,12 +751,13 @@ self.assertEqual(e2.validator, "enum") self.assertEqual(e2.validator_value, [2]) self.assertEqual(e2.instance, 1) - self.assertEqual(e2.schema, {u"enum": [2]}) + self.assertEqual(e2.schema, {"enum": [2]}) self.assertIs(e2.parent, e) self.assertEqual(e2.path, deque(["foo"])) self.assertEqual(e2.relative_path, deque(["foo"])) self.assertEqual(e2.absolute_path, deque(["foo"])) + self.assertEqual(e2.json_path, "$.foo") self.assertEqual( e2.schema_path, deque([1, "properties", "foo", "enum"]), @@ -776,6 +801,11 @@ self.assertEqual(e3.absolute_path, deque(["baz"])) self.assertEqual(e4.absolute_path, deque(["foo"])) + self.assertEqual(e1.json_path, "$.bar") + self.assertEqual(e2.json_path, "$.baz") + self.assertEqual(e3.json_path, "$.baz") + self.assertEqual(e4.json_path, "$.foo") + self.assertEqual(e1.validator, "minItems") self.assertEqual(e2.validator, "enum") self.assertEqual(e3.validator, "maximum") @@ -811,6 +841,13 @@ self.assertEqual(e5.path, deque([1, "bar", "baz"])) self.assertEqual(e6.path, deque([1, "foo"])) + self.assertEqual(e1.json_path, "$") + self.assertEqual(e2.json_path, "$[0]") + self.assertEqual(e3.json_path, "$[1].bar") + self.assertEqual(e4.json_path, "$[1].bar.bar") + self.assertEqual(e5.json_path, "$[1].bar.baz") + self.assertEqual(e6.json_path, "$[1].foo") + self.assertEqual(e1.schema_path, deque(["type"])) self.assertEqual(e2.schema_path, deque(["items", "type"])) self.assertEqual( @@ -822,7 +859,7 @@ ) self.assertEqual( list(e5.schema_path), - ["items", "properties", "bar", "properties", "baz", "minItems"] + ["items", "properties", "bar", "properties", "baz", "minItems"], ) self.assertEqual( list(e6.schema_path), ["items", "properties", "foo", "enum"], @@ -886,6 +923,7 @@ self.assertEqual( e.absolute_schema_path, deque(["properties", "root", "anyOf"]), ) + self.assertEqual(e.json_path, "$.root") e1, = e.context self.assertEqual(e1.absolute_path, deque(["root", "children", "a"])) @@ -904,6 +942,7 @@ ], ), ) + self.assertEqual(e1.json_path, "$.root.children.a") e2, = e1.context self.assertEqual( @@ -932,6 +971,7 @@ ], ), ) + self.assertEqual(e2.json_path, "$.root.children.a.children.ab") def test_additionalProperties(self): instance = {"bar": "bar", "foo": 2} @@ -944,6 +984,9 @@ self.assertEqual(e1.path, deque(["bar"])) self.assertEqual(e2.path, deque(["foo"])) + self.assertEqual(e1.json_path, "$.bar") + self.assertEqual(e2.json_path, "$.foo") + self.assertEqual(e1.validator, "type") self.assertEqual(e2.validator, "minimum") @@ -963,6 +1006,9 @@ self.assertEqual(e1.path, deque(["bar"])) self.assertEqual(e2.path, deque(["foo"])) + self.assertEqual(e1.json_path, "$.bar") + self.assertEqual(e2.json_path, "$.foo") + self.assertEqual(e1.validator, "type") self.assertEqual(e2.validator, "minimum") @@ -980,6 +1026,9 @@ self.assertEqual(e1.path, deque([0])) self.assertEqual(e2.path, deque([1])) + self.assertEqual(e1.json_path, "$[0]") + self.assertEqual(e2.json_path, "$[1]") + self.assertEqual(e1.validator, "type") self.assertEqual(e2.validator, "minimum") @@ -997,6 +1046,9 @@ self.assertEqual(e1.path, deque([1])) self.assertEqual(e2.path, deque([2])) + self.assertEqual(e1.json_path, "$[1]") + self.assertEqual(e2.json_path, "$[2]") + self.assertEqual(e1.validator, "type") self.assertEqual(e2.validator, "minimum") @@ -1010,9 +1062,10 @@ self.assertEqual(error.validator, "not") self.assertEqual( error.message, - "%r is not allowed for %r" % ({"const": "foo"}, "foo"), + "'foo' should not be valid under {'const': 'foo'}", ) self.assertEqual(error.path, deque([])) + self.assertEqual(error.json_path, "$") self.assertEqual(error.schema_path, deque(["propertyNames", "not"])) def test_if_then(self): @@ -1027,7 +1080,8 @@ self.assertEqual(error.validator, "const") self.assertEqual(error.message, "13 was expected") self.assertEqual(error.path, deque([])) - self.assertEqual(error.schema_path, deque(["if", "then", "const"])) + self.assertEqual(error.json_path, "$") + self.assertEqual(error.schema_path, deque(["then", "const"])) def test_if_else(self): schema = { @@ -1041,7 +1095,8 @@ self.assertEqual(error.validator, "const") self.assertEqual(error.message, "13 was expected") self.assertEqual(error.path, deque([])) - self.assertEqual(error.schema_path, deque(["if", "else", "const"])) + self.assertEqual(error.json_path, "$") + self.assertEqual(error.schema_path, deque(["else", "const"])) def test_boolean_schema_False(self): validator = validators.Draft7Validator(False) @@ -1055,6 +1110,7 @@ error.instance, error.schema, error.schema_path, + error.json_path, ), ( "False schema does not allow 12", @@ -1063,6 +1119,7 @@ 12, False, deque([]), + "$", ), ) @@ -1083,6 +1140,7 @@ error.absolute_path, error.schema, error.schema_path, + error.json_path, ), ( "'notAnInteger' is not of type 'integer'", @@ -1092,6 +1150,258 @@ deque(["foo"]), {"type": "integer"}, deque(["additionalProperties", "type"]), + "$.foo", + ), + ) + + def test_prefixItems(self): + schema = {"prefixItems": [{"type": "string"}, {}, {}, {"maximum": 3}]} + validator = validators.Draft202012Validator(schema) + type_error, min_error = validator.iter_errors([1, 2, "foo", 5]) + self.assertEqual( + ( + type_error.message, + type_error.validator, + type_error.validator_value, + type_error.instance, + type_error.absolute_path, + type_error.schema, + type_error.schema_path, + type_error.json_path, + ), + ( + "1 is not of type 'string'", + "type", + "string", + 1, + deque([0]), + {"type": "string"}, + deque(["prefixItems", 0, "type"]), + "$[0]", + ), + ) + self.assertEqual( + ( + min_error.message, + min_error.validator, + min_error.validator_value, + min_error.instance, + min_error.absolute_path, + min_error.schema, + min_error.schema_path, + min_error.json_path, + ), + ( + "5 is greater than the maximum of 3", + "maximum", + 3, + 5, + deque([3]), + {"maximum": 3}, + deque(["prefixItems", 3, "maximum"]), + "$[3]", + ), + ) + + def test_prefixItems_with_items(self): + schema = { + "items": {"type": "string"}, + "prefixItems": [{}], + } + validator = validators.Draft202012Validator(schema) + e1, e2 = validator.iter_errors(["foo", 2, "bar", 4, "baz"]) + self.assertEqual( + ( + e1.message, + e1.validator, + e1.validator_value, + e1.instance, + e1.absolute_path, + e1.schema, + e1.schema_path, + e1.json_path, + ), + ( + "2 is not of type 'string'", + "type", + "string", + 2, + deque([1]), + {"type": "string"}, + deque(["items", "type"]), + "$[1]", + ), + ) + self.assertEqual( + ( + e2.message, + e2.validator, + e2.validator_value, + e2.instance, + e2.absolute_path, + e2.schema, + e2.schema_path, + e2.json_path, + ), + ( + "4 is not of type 'string'", + "type", + "string", + 4, + deque([3]), + {"type": "string"}, + deque(["items", "type"]), + "$[3]", + ), + ) + + def test_contains_too_many(self): + """ + `contains` + `maxContains` produces only one error, even if there are + many more incorrectly matching elements. + """ + schema = {"contains": {"type": "string"}, "maxContains": 2} + validator = validators.Draft202012Validator(schema) + error, = validator.iter_errors(["foo", 2, "bar", 4, "baz", "quux"]) + self.assertEqual( + ( + error.message, + error.validator, + error.validator_value, + error.instance, + error.absolute_path, + error.schema, + error.schema_path, + error.json_path, + ), + ( + "Too many items match the given schema (expected at most 2)", + "maxContains", + 2, + ["foo", 2, "bar", 4, "baz", "quux"], + deque([]), + {"contains": {"type": "string"}, "maxContains": 2}, + deque(["contains"]), + "$", + ), + ) + + def test_contains_too_few(self): + schema = {"contains": {"type": "string"}, "minContains": 2} + validator = validators.Draft202012Validator(schema) + error, = validator.iter_errors(["foo", 2, 4]) + self.assertEqual( + ( + error.message, + error.validator, + error.validator_value, + error.instance, + error.absolute_path, + error.schema, + error.schema_path, + error.json_path, + ), + ( + ( + "Too few items match the given schema " + "(expected at least 2 but only 1 matched)" + ), + "minContains", + 2, + ["foo", 2, 4], + deque([]), + {"contains": {"type": "string"}, "minContains": 2}, + deque(["contains"]), + "$", + ), + ) + + def test_contains_none(self): + schema = {"contains": {"type": "string"}, "minContains": 2} + validator = validators.Draft202012Validator(schema) + error, = validator.iter_errors([2, 4]) + self.assertEqual( + ( + error.message, + error.validator, + error.validator_value, + error.instance, + error.absolute_path, + error.schema, + error.schema_path, + error.json_path, + ), + ( + "[2, 4] does not contain items matching the given schema", + "contains", + {"type": "string"}, + [2, 4], + deque([]), + {"contains": {"type": "string"}, "minContains": 2}, + deque(["contains"]), + "$", + ), + ) + + def test_ref_sibling(self): + schema = { + "$defs": {"foo": {"required": ["bar"]}}, + "properties": { + "aprop": { + "$ref": "#/$defs/foo", + "required": ["baz"], + }, + }, + } + + validator = validators.Draft202012Validator(schema) + e1, e2 = validator.iter_errors({"aprop": {}}) + self.assertEqual( + ( + e1.message, + e1.validator, + e1.validator_value, + e1.instance, + e1.absolute_path, + e1.schema, + e1.schema_path, + e1.relative_schema_path, + e1.json_path, + ), + ( + "'bar' is a required property", + "required", + ["bar"], + {}, + deque(["aprop"]), + {"required": ["bar"]}, + deque(["properties", "aprop", "required"]), + deque(["properties", "aprop", "required"]), + "$.aprop", + ), + ) + self.assertEqual( + ( + e2.message, + e2.validator, + e2.validator_value, + e2.instance, + e2.absolute_path, + e2.schema, + e2.schema_path, + e2.relative_schema_path, + e2.json_path, + ), + ( + "'baz' is a required property", + "required", + ["baz"], + {}, + deque(["aprop"]), + {"$ref": "#/$defs/foo", "required": ["baz"]}, + deque(["properties", "aprop", "required"]), + deque(["properties", "aprop", "required"]), + "$.aprop", ), ) @@ -1111,7 +1421,7 @@ """ Technically, all the spec says is they SHOULD have elements, not MUST. - See https://github.com/Julian/jsonschema/issues/529. + See #529. """ self.Validator.check_schema({"enum": []}) @@ -1119,12 +1429,15 @@ """ Technically, all the spec says is they SHOULD be unique, not MUST. - See https://github.com/Julian/jsonschema/issues/529. + See #529. """ self.Validator.check_schema({"enum": [12, 12]}) class ValidatorTestMixin(MetaSchemaTestsMixin, object): + def test_it_implements_the_validator_protocol(self): + self.assertIsInstance(self.Validator({}), protocols.Validator) + def test_valid_instances_are_valid(self): schema, instance = self.valid self.assertTrue(self.Validator(schema).is_valid(instance)) @@ -1178,16 +1491,6 @@ self.assertFalse(self.Validator({}).is_type(True, "integer")) self.assertFalse(self.Validator({}).is_type(True, "number")) - @unittest.skipIf(PY3, "In Python 3 json.load always produces unicode") - def test_string_a_bytestring_is_a_string(self): - self.Validator({"type": "string"}).validate(b"foo") - - def test_patterns_can_be_native_strings(self): - """ - See https://github.com/Julian/jsonschema/issues/611. - """ - self.Validator({"pattern": "foo"}).validate("foo") - def test_it_can_validate_with_decimals(self): schema = {"items": {"type": "number"}} Validator = validators.extend( @@ -1197,7 +1500,7 @@ lambda checker, thing: isinstance( thing, (int, float, Decimal), ) and not isinstance(thing, bool), - ) + ), ) validator = Validator(schema) @@ -1251,7 +1554,7 @@ type_checker=self.Validator.TYPE_CHECKER.redefine( non_string_type, lambda checker, thing: isinstance(thing, int), - ) + ), ) Crazy(schema).validate(15) @@ -1259,19 +1562,85 @@ """ A tuple instance properly formats validation errors for uniqueItems. - See https://github.com/Julian/jsonschema/pull/224 + See #224 """ TupleValidator = validators.extend( self.Validator, type_checker=self.Validator.TYPE_CHECKER.redefine( "array", lambda checker, thing: isinstance(thing, tuple), - ) + ), ) with self.assertRaises(exceptions.ValidationError) as e: TupleValidator({"uniqueItems": True}).validate((1, 1)) self.assertIn("(1, 1) has non-unique elements", str(e.exception)) + def test_check_redefined_sequence(self): + """ + Allow array to validate against another defined sequence type + """ + schema = {"type": "array", "uniqueItems": True} + MyMapping = namedtuple("MyMapping", "a, b") + Validator = validators.extend( + self.Validator, + type_checker=self.Validator.TYPE_CHECKER.redefine_many( + { + "array": lambda checker, thing: isinstance( + thing, (list, deque), + ), + "object": lambda checker, thing: isinstance( + thing, (dict, MyMapping), + ), + }, + ), + ) + validator = Validator(schema) + + valid_instances = [ + deque(["a", None, "1", "", True]), + deque([[False], [0]]), + [deque([False]), deque([0])], + [[deque([False])], [deque([0])]], + [[[[[deque([False])]]]], [[[[deque([0])]]]]], + [deque([deque([False])]), deque([deque([0])])], + [MyMapping("a", 0), MyMapping("a", False)], + [ + MyMapping("a", [deque([0])]), + MyMapping("a", [deque([False])]), + ], + [ + MyMapping("a", [MyMapping("a", deque([0]))]), + MyMapping("a", [MyMapping("a", deque([False]))]), + ], + [deque(deque(deque([False]))), deque(deque(deque([0])))], + ] + + for instance in valid_instances: + validator.validate(instance) + + invalid_instances = [ + deque(["a", "b", "a"]), + deque([[False], [False]]), + [deque([False]), deque([False])], + [[deque([False])], [deque([False])]], + [[[[[deque([False])]]]], [[[[deque([False])]]]]], + [deque([deque([False])]), deque([deque([False])])], + [MyMapping("a", False), MyMapping("a", False)], + [ + MyMapping("a", [deque([False])]), + MyMapping("a", [deque([False])]), + ], + [ + MyMapping("a", [MyMapping("a", deque([False]))]), + MyMapping("a", [MyMapping("a", deque([False]))]), + ], + [deque(deque(deque([False]))), deque(deque(deque([False])))], + ] + + for instance in invalid_instances: + with self.assertRaises(exceptions.ValidationError): + validator.validate(instance) + class AntiDraft6LeakMixin(object): """ @@ -1305,7 +1674,7 @@ class TestDraft3Validator(AntiDraft6LeakMixin, ValidatorTestMixin, TestCase): Validator = validators.Draft3Validator - valid = {}, {} + valid: tuple[dict, dict] = ({}, {}) invalid = {"type": "integer"}, "foo" def test_any_type_is_valid_for_type_any(self): @@ -1320,7 +1689,7 @@ self.Validator, type_checker=self.Validator.TYPE_CHECKER.redefine( "any", lambda checker, thing: isinstance(thing, int), - ) + ), ) validator = Crazy({"type": "any"}) validator.validate(12) @@ -1328,32 +1697,44 @@ validator.validate("foo") def test_is_type_is_true_for_any_type(self): - self.assertTrue(self.Validator({}).is_valid(object(), {"type": "any"})) + self.assertTrue(self.Validator({"type": "any"}).is_valid(object())) def test_is_type_does_not_evade_bool_if_it_is_being_tested(self): self.assertTrue(self.Validator({}).is_type(True, "boolean")) - self.assertTrue(self.Validator({}).is_valid(True, {"type": "any"})) + self.assertTrue(self.Validator({"type": "any"}).is_valid(True)) class TestDraft4Validator(AntiDraft6LeakMixin, ValidatorTestMixin, TestCase): Validator = validators.Draft4Validator - valid = {}, {} + valid: tuple[dict, dict] = ({}, {}) invalid = {"type": "integer"}, "foo" class TestDraft6Validator(ValidatorTestMixin, TestCase): Validator = validators.Draft6Validator - valid = {}, {} + valid: tuple[dict, dict] = ({}, {}) invalid = {"type": "integer"}, "foo" class TestDraft7Validator(ValidatorTestMixin, TestCase): Validator = validators.Draft7Validator - valid = {}, {} + valid: tuple[dict, dict] = ({}, {}) invalid = {"type": "integer"}, "foo" -class TestValidatorFor(SynchronousTestCase): +class TestDraft201909Validator(ValidatorTestMixin, TestCase): + Validator = validators.Draft201909Validator + valid: tuple[dict, dict] = ({}, {}) + invalid = {"type": "integer"}, "foo" + + +class TestDraft202012Validator(ValidatorTestMixin, TestCase): + Validator = validators.Draft202012Validator + valid: tuple[dict, dict] = ({}, {}) + invalid = {"type": "integer"}, "foo" + + +class TestValidatorFor(TestCase): def test_draft_3(self): schema = {"$schema": "http://json-schema.org/draft-03/schema"} self.assertIs( @@ -1406,6 +1787,32 @@ validators.Draft7Validator, ) + def test_draft_201909(self): + schema = {"$schema": "https://json-schema.org/draft/2019-09/schema"} + self.assertIs( + validators.validator_for(schema), + validators.Draft201909Validator, + ) + + schema = {"$schema": "https://json-schema.org/draft/2019-09/schema#"} + self.assertIs( + validators.validator_for(schema), + validators.Draft201909Validator, + ) + + def test_draft_202012(self): + schema = {"$schema": "https://json-schema.org/draft/2020-12/schema"} + self.assertIs( + validators.validator_for(schema), + validators.Draft202012Validator, + ) + + schema = {"$schema": "https://json-schema.org/draft/2020-12/schema#"} + self.assertIs( + validators.validator_for(schema), + validators.Draft202012Validator, + ) + def test_True(self): self.assertIs( validators.validator_for(True), @@ -1448,31 +1855,29 @@ self.assertIs(validators.validator_for({}, default=None), None) def test_warns_if_meta_schema_specified_was_not_found(self): - self.assertWarns( - category=DeprecationWarning, - message=( - "The metaschema specified by $schema was not found. " - "Using the latest draft to validate, but this will raise " - "an error in the future." - ), - # https://tm.tl/9363 :'( - filename=sys.modules[self.assertWarns.__module__].__file__, - - f=validators.validator_for, - schema={u"$schema": "unknownSchema"}, - default={}, + with self.assertWarns(DeprecationWarning) as cm: + validators.validator_for(schema={"$schema": "unknownSchema"}) + + self.assertEqual(cm.filename, __file__) + self.assertEqual( + str(cm.warning), + "The metaschema specified by $schema was not found. " + "Using the latest draft to validate, but this will raise " + "an error in the future.", ) def test_does_not_warn_if_meta_schema_is_unspecified(self): - validators.validator_for(schema={}, default={}), - self.assertFalse(self.flushWarnings()) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + validators.validator_for(schema={}, default={}) + self.assertFalse(w) -class TestValidate(SynchronousTestCase): +class TestValidate(TestCase): def assertUses(self, schema, Validator): result = [] - self.patch(Validator, "check_schema", result.append) - validators.validate({}, schema) + with mock.patch.object(Validator, "check_schema", result.append): + validators.validate({}, schema) self.assertEqual(result, [schema]) def test_draft3_validator_is_chosen(self): @@ -1519,23 +1924,38 @@ Validator=validators.Draft7Validator, ) - def test_draft7_validator_is_the_default(self): - self.assertUses(schema={}, Validator=validators.Draft7Validator) + def test_draft202012_validator_is_chosen(self): + self.assertUses( + schema={ + "$schema": "https://json-schema.org/draft/2020-12/schema#", + }, + Validator=validators.Draft202012Validator, + ) + # Make sure it works without the empty fragment + self.assertUses( + schema={ + "$schema": "https://json-schema.org/draft/2020-12/schema", + }, + Validator=validators.Draft202012Validator, + ) + + def test_draft202012_validator_is_the_default(self): + self.assertUses(schema={}, Validator=validators.Draft202012Validator) def test_validation_error_message(self): with self.assertRaises(exceptions.ValidationError) as e: validators.validate(12, {"type": "string"}) - self.assertRegexpMatches( + self.assertRegex( str(e.exception), - "(?s)Failed validating u?'.*' in schema.*On instance", + "(?s)Failed validating '.*' in schema.*On instance", ) def test_schema_error_message(self): with self.assertRaises(exceptions.SchemaError) as e: validators.validate(12, {"type": 12}) - self.assertRegexpMatches( + self.assertRegex( str(e.exception), - "(?s)Failed validating u?'.*' in metaschema.*On schema", + "(?s)Failed validating '.*' in metaschema.*On schema", ) def test_it_uses_best_match(self): @@ -1546,7 +1966,7 @@ self.assertIn("12 is not of type", str(e.exception)) -class TestRefResolver(SynchronousTestCase): +class TestRefResolver(TestCase): base_uri = "" stored_uri = "foo://stored" @@ -1561,14 +1981,11 @@ def test_it_does_not_retrieve_schema_urls_from_the_network(self): ref = validators.Draft3Validator.META_SCHEMA["id"] - self.patch( - self.resolver, - "resolve_remote", - lambda *args, **kwargs: self.fail("Should not have been called!"), - ) - with self.resolver.resolving(ref) as resolved: - pass + with mock.patch.object(self.resolver, "resolve_remote") as patched: + with self.resolver.resolving(ref) as resolved: + pass self.assertEqual(resolved, validators.Draft3Validator.META_SCHEMA) + self.assertFalse(patched.called) def test_it_resolves_local_refs(self): ref = "#/properties/foo" @@ -1580,7 +1997,7 @@ schema = {"id": "http://bar/schema#", "a": {"foo": "bar"}} resolver = validators.RefResolver.from_schema( schema, - id_of=lambda schema: schema.get(u"id", u""), + id_of=lambda schema: schema.get("id", ""), ) with resolver.resolving("#/a") as resolved: self.assertEqual(resolved, schema["a"]) @@ -1643,7 +2060,7 @@ schema = {"id": "foo"} resolver = validators.RefResolver.from_schema( schema, - id_of=lambda schema: schema.get(u"id", u""), + id_of=lambda schema: schema.get("id", ""), ) self.assertEqual(resolver.base_uri, "foo") self.assertEqual(resolver.resolution_scope, "foo") diff -Nru python-jsonschema-3.2.0/jsonschema/_types.py python-jsonschema-4.6.0/jsonschema/_types.py --- python-jsonschema-3.2.0/jsonschema/_types.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/_types.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,12 +1,33 @@ +from __future__ import annotations + import numbers +import typing from pyrsistent import pmap import attr -from jsonschema.compat import int_types, str_types from jsonschema.exceptions import UndefinedTypeCheck +# unfortunately, the type of pmap is generic, and if used as the attr.ib +# converter, the generic type is presented to mypy, which then fails to match +# the concrete type of a type checker mapping +# this "do nothing" wrapper presents the correct information to mypy +def _typed_pmap_converter( + init_val: typing.Mapping[ + str, + typing.Callable[["TypeChecker", typing.Any], bool], + ], +) -> typing.Mapping[str, typing.Callable[["TypeChecker", typing.Any], bool]]: + return typing.cast( + typing.Mapping[ + str, + typing.Callable[["TypeChecker", typing.Any], bool], + ], + pmap(init_val), + ) + + def is_array(checker, instance): return isinstance(instance, list) @@ -19,7 +40,7 @@ # bool inherits from int, so ensure bools aren't reported as ints if isinstance(instance, bool): return False - return isinstance(instance, int_types) + return isinstance(instance, int) def is_null(checker, instance): @@ -38,7 +59,7 @@ def is_string(checker, instance): - return isinstance(instance, str_types) + return isinstance(instance, str) def is_any(checker, instance): @@ -50,7 +71,7 @@ """ A ``type`` property checker. - A `TypeChecker` performs type checking for an `IValidator`. Type + A `TypeChecker` performs type checking for a `Validator`. Type checks to perform are updated using `TypeChecker.redefine` or `TypeChecker.redefine_many` and removed via `TypeChecker.remove`. Each of these return a new `TypeChecker` object. @@ -61,7 +82,13 @@ The initial mapping of types to their checking functions. """ - _type_checkers = attr.ib(default=pmap(), converter=pmap) + + _type_checkers: typing.Mapping[ + str, typing.Callable[["TypeChecker", typing.Any], bool], + ] = attr.ib( + default=pmap(), + converter=_typed_pmap_converter, + ) def is_type(self, instance, type): """ @@ -90,7 +117,7 @@ try: fn = self._type_checkers[type] except KeyError: - raise UndefinedTypeCheck(type) + raise UndefinedTypeCheck(type) from None return fn(self, instance) @@ -104,7 +131,7 @@ The name of the type to check. - fn (collections.Callable): + fn (collections.abc.Callable): A function taking exactly two parameters - the type checker calling the function and the instance to check. @@ -141,7 +168,7 @@ Arguments: - types (~collections.Iterable): + types (~collections.abc.Iterable): the names of the types to remove. @@ -167,22 +194,24 @@ draft3_type_checker = TypeChecker( { - u"any": is_any, - u"array": is_array, - u"boolean": is_bool, - u"integer": is_integer, - u"object": is_object, - u"null": is_null, - u"number": is_number, - u"string": is_string, + "any": is_any, + "array": is_array, + "boolean": is_bool, + "integer": is_integer, + "object": is_object, + "null": is_null, + "number": is_number, + "string": is_string, }, ) -draft4_type_checker = draft3_type_checker.remove(u"any") +draft4_type_checker = draft3_type_checker.remove("any") draft6_type_checker = draft4_type_checker.redefine( - u"integer", + "integer", lambda checker, instance: ( - is_integer(checker, instance) or - isinstance(instance, float) and instance.is_integer() + is_integer(checker, instance) + or isinstance(instance, float) and instance.is_integer() ), ) draft7_type_checker = draft6_type_checker +draft201909_type_checker = draft7_type_checker +draft202012_type_checker = draft201909_type_checker diff -Nru python-jsonschema-3.2.0/jsonschema/_utils.py python-jsonschema-4.6.0/jsonschema/_utils.py --- python-jsonschema-3.2.0/jsonschema/_utils.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/_utils.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,9 +1,15 @@ +from collections.abc import Mapping, MutableMapping, Sequence +from urllib.parse import urlsplit import itertools import json -import pkgutil import re +import sys -from jsonschema.compat import MutableMapping, str_types, urlsplit +# The files() API was added in Python 3.9. +if sys.version_info >= (3, 9): # pragma: no cover + from importlib import resources +else: # pragma: no cover + import importlib_resources as resources # type: ignore class URIDict(MutableMapping): @@ -51,34 +57,31 @@ Load a schema from ./schemas/``name``.json and return it. """ - data = pkgutil.get_data("jsonschema", "schemas/{0}.json".format(name)) - return json.loads(data.decode("utf-8")) + path = resources.files(__package__).joinpath(f"schemas/{name}.json") + data = path.read_text(encoding="utf-8") + return json.loads(data) -def indent(string, times=1): - """ - A dumb version of `textwrap.indent` from Python 3.3. - """ - - return "\n".join(" " * (4 * times) + line for line in string.splitlines()) - - -def format_as_index(indices): +def format_as_index(container, indices): """ Construct a single string containing indexing operations for the indices. - For example, [1, 2, "foo"] -> [1][2]["foo"] + For example for a container ``bar``, [1, 2, "foo"] -> bar[1][2]["foo"] Arguments: + container (str): + + A word to use for the thing being indexed + indices (sequence): The indices to format. """ if not indices: - return "" - return "[%s]" % "][".join(repr(index) for index in indices) + return container + return f"{container}[{']['.join(repr(index) for index in indices)}]" def find_additional_properties(instance, schema): @@ -109,66 +112,55 @@ verb = "was" else: verb = "were" - return ", ".join(repr(extra) for extra in extras), verb + return ", ".join(repr(extra) for extra in sorted(extras)), verb -def types_msg(instance, types): +def ensure_list(thing): """ - Create an error message for a failure to match the given types. - - If the ``instance`` is an object and contains a ``name`` property, it will - be considered to be a description of that object and used as its type. + Wrap ``thing`` in a list if it's a single str. - Otherwise the message is simply the reprs of the given ``types``. + Otherwise, return it unchanged. """ - reprs = [] - for type in types: - try: - reprs.append(repr(type["name"])) - except Exception: - reprs.append(repr(type)) - return "%r is not of type %s" % (instance, ", ".join(reprs)) + if isinstance(thing, str): + return [thing] + return thing -def flatten(suitable_for_isinstance): +def _mapping_equal(one, two): """ - isinstance() can accept a bunch of really annoying different types: - * a single type - * a tuple of types - * an arbitrary nested tree of tuples - - Return a flattened tuple of the given argument. + Check if two mappings are equal using the semantics of `equal`. """ - - types = set() - - if not isinstance(suitable_for_isinstance, tuple): - suitable_for_isinstance = (suitable_for_isinstance,) - for thing in suitable_for_isinstance: - if isinstance(thing, tuple): - types.update(flatten(thing)) - else: - types.add(thing) - return tuple(types) + if len(one) != len(two): + return False + return all( + key in two and equal(value, two[key]) + for key, value in one.items() + ) -def ensure_list(thing): +def _sequence_equal(one, two): """ - Wrap ``thing`` in a list if it's a single str. - - Otherwise, return it unchanged. + Check if two sequences are equal using the semantics of `equal`. """ - - if isinstance(thing, str_types): - return [thing] - return thing + if len(one) != len(two): + return False + return all(equal(i, j) for i, j in zip(one, two)) def equal(one, two): """ - Check if two things are equal, but evade booleans and ints being equal. + Check if two things are equal evading some Python type hierarchy semantics. + + Specifically in JSON Schema, evade `bool` inheriting from `int`, + recursing into sequences to do the same. """ + if isinstance(one, str) or isinstance(two, str): + return one == two + if isinstance(one, Sequence) and isinstance(two, Sequence): + return _sequence_equal(one, two) + if isinstance(one, Mapping) and isinstance(two, Mapping): + return _mapping_equal(one, two) return unbool(one) == unbool(two) @@ -188,25 +180,169 @@ """ Check if all of a container's elements are unique. - Successively tries first to rely that the elements are hashable, then - falls back on them being sortable, and finally falls back on brute - force. + Tries to rely on the container being recursively sortable, or otherwise + falls back on (slow) brute force. """ - try: - return len(set(unbool(i) for i in container)) == len(container) - except TypeError: - try: - sort = sorted(unbool(i) for i in container) - sliced = itertools.islice(sort, 1, None) - for i, j in zip(sort, sliced): - if i == j: - return False - except (NotImplementedError, TypeError): - seen = [] - for e in container: - e = unbool(e) - if e in seen: + sort = sorted(unbool(i) for i in container) + sliced = itertools.islice(sort, 1, None) + + for i, j in zip(sort, sliced): + if equal(i, j): + return False + + except (NotImplementedError, TypeError): + seen = [] + for e in container: + e = unbool(e) + + for i in seen: + if equal(i, e): return False - seen.append(e) + + seen.append(e) return True + + +def find_evaluated_item_indexes_by_schema(validator, instance, schema): + """ + Get all indexes of items that get evaluated under the current schema + + Covers all keywords related to unevaluatedItems: items, prefixItems, if, + then, else, contains, unevaluatedItems, allOf, oneOf, anyOf + """ + if validator.is_type(schema, "boolean"): + return [] + evaluated_indexes = [] + + if "items" in schema: + return list(range(0, len(instance))) + + if "$ref" in schema: + scope, resolved = validator.resolver.resolve(schema["$ref"]) + validator.resolver.push_scope(scope) + + try: + evaluated_indexes += find_evaluated_item_indexes_by_schema( + validator, instance, resolved) + finally: + validator.resolver.pop_scope() + + if "prefixItems" in schema: + evaluated_indexes += list(range(0, len(schema["prefixItems"]))) + + if "if" in schema: + if validator.evolve(schema=schema["if"]).is_valid(instance): + evaluated_indexes += find_evaluated_item_indexes_by_schema( + validator, instance, schema["if"], + ) + if "then" in schema: + evaluated_indexes += find_evaluated_item_indexes_by_schema( + validator, instance, schema["then"], + ) + else: + if "else" in schema: + evaluated_indexes += find_evaluated_item_indexes_by_schema( + validator, instance, schema["else"], + ) + + for keyword in ["contains", "unevaluatedItems"]: + if keyword in schema: + for k, v in enumerate(instance): + if validator.evolve(schema=schema[keyword]).is_valid(v): + evaluated_indexes.append(k) + + for keyword in ["allOf", "oneOf", "anyOf"]: + if keyword in schema: + for subschema in schema[keyword]: + errs = list(validator.descend(instance, subschema)) + if not errs: + evaluated_indexes += find_evaluated_item_indexes_by_schema( + validator, instance, subschema, + ) + + return evaluated_indexes + + +def find_evaluated_property_keys_by_schema(validator, instance, schema): + """ + Get all keys of items that get evaluated under the current schema + + Covers all keywords related to unevaluatedProperties: properties, + additionalProperties, unevaluatedProperties, patternProperties, + dependentSchemas, allOf, oneOf, anyOf, if, then, else + """ + if validator.is_type(schema, "boolean"): + return [] + evaluated_keys = [] + + if "$ref" in schema: + scope, resolved = validator.resolver.resolve(schema["$ref"]) + validator.resolver.push_scope(scope) + + try: + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, resolved, + ) + finally: + validator.resolver.pop_scope() + + for keyword in [ + "properties", "additionalProperties", "unevaluatedProperties", + ]: + if keyword in schema: + if validator.is_type(schema[keyword], "boolean"): + for property, value in instance.items(): + if validator.evolve(schema=schema[keyword]).is_valid( + {property: value}, + ): + evaluated_keys.append(property) + + if validator.is_type(schema[keyword], "object"): + for property, subschema in schema[keyword].items(): + if property in instance and validator.evolve( + schema=subschema, + ).is_valid(instance[property]): + evaluated_keys.append(property) + + if "patternProperties" in schema: + for property, value in instance.items(): + for pattern, _ in schema["patternProperties"].items(): + if re.search(pattern, property) and validator.evolve( + schema=schema["patternProperties"], + ).is_valid({property: value}): + evaluated_keys.append(property) + + if "dependentSchemas" in schema: + for property, subschema in schema["dependentSchemas"].items(): + if property not in instance: + continue + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, subschema, + ) + + for keyword in ["allOf", "oneOf", "anyOf"]: + if keyword in schema: + for subschema in schema[keyword]: + errs = list(validator.descend(instance, subschema)) + if not errs: + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, subschema, + ) + + if "if" in schema: + if validator.evolve(schema=schema["if"]).is_valid(instance): + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, schema["if"], + ) + if "then" in schema: + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, schema["then"], + ) + else: + if "else" in schema: + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, schema["else"], + ) + + return evaluated_keys diff -Nru python-jsonschema-3.2.0/jsonschema/_validators.py python-jsonschema-4.6.0/jsonschema/_validators.py --- python-jsonschema-3.2.0/jsonschema/_validators.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/_validators.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,3 +1,5 @@ +from fractions import Fraction +from urllib.parse import urldefrag, urljoin import re from jsonschema._utils import ( @@ -5,25 +7,24 @@ equal, extras_msg, find_additional_properties, - types_msg, + find_evaluated_item_indexes_by_schema, + find_evaluated_property_keys_by_schema, unbool, uniq, ) from jsonschema.exceptions import FormatError, ValidationError -from jsonschema.compat import iteritems def patternProperties(validator, patternProperties, instance, schema): if not validator.is_type(instance, "object"): return - for pattern, subschema in iteritems(patternProperties): - for k, v in iteritems(instance): + for pattern, subschema in patternProperties.items(): + for k, v in instance.items(): if re.search(pattern, k): - for error in validator.descend( + yield from validator.descend( v, subschema, path=k, schema_path=pattern, - ): - yield error + ) def propertyNames(validator, propertyNames, instance, schema): @@ -31,11 +32,7 @@ return for property in instance: - for error in validator.descend( - instance=property, - schema=propertyNames, - ): - yield error + yield from validator.descend(instance=property, schema=propertyNames) def additionalProperties(validator, aP, instance, schema): @@ -46,20 +43,19 @@ if validator.is_type(aP, "object"): for extra in extras: - for error in validator.descend(instance[extra], aP, path=extra): - yield error + yield from validator.descend(instance[extra], aP, path=extra) elif not aP and extras: if "patternProperties" in schema: - patterns = sorted(schema["patternProperties"]) if len(extras) == 1: verb = "does" else: verb = "do" - error = "%s %s not match any of the regexes: %s" % ( - ", ".join(map(repr, sorted(extras))), - verb, - ", ".join(map(repr, patterns)), + + joined = ", ".join(repr(each) for each in sorted(extras)) + patterns = ", ".join( + repr(each) for each in sorted(schema["patternProperties"]) ) + error = f"{joined} {verb} not match any of the regexes: {patterns}" yield ValidationError(error) else: error = "Additional properties are not allowed (%s %s unexpected)" @@ -70,51 +66,76 @@ if not validator.is_type(instance, "array"): return - if validator.is_type(items, "array"): - for (index, item), subschema in zip(enumerate(instance), items): - for error in validator.descend( - item, subschema, path=index, schema_path=index, - ): - yield error + prefix = len(schema.get("prefixItems", [])) + total = len(instance) + if items is False and total > prefix: + message = f"Expected at most {prefix} items, but found {total}" + yield ValidationError(message) else: - for index, item in enumerate(instance): - for error in validator.descend(item, items, path=index): - yield error + for index in range(prefix, total): + yield from validator.descend( + instance=instance[index], + schema=items, + path=index, + ) def additionalItems(validator, aI, instance, schema): if ( - not validator.is_type(instance, "array") or - validator.is_type(schema.get("items", {}), "object") + not validator.is_type(instance, "array") + or validator.is_type(schema.get("items", {}), "object") ): return len_items = len(schema.get("items", [])) if validator.is_type(aI, "object"): for index, item in enumerate(instance[len_items:], start=len_items): - for error in validator.descend(item, aI, path=index): - yield error + yield from validator.descend(item, aI, path=index) elif not aI and len(instance) > len(schema.get("items", [])): error = "Additional items are not allowed (%s %s unexpected)" yield ValidationError( - error % - extras_msg(instance[len(schema.get("items", [])):]) + error % extras_msg(instance[len(schema.get("items", [])):]), ) def const(validator, const, instance, schema): if not equal(instance, const): - yield ValidationError("%r was expected" % (const,)) + yield ValidationError(f"{const!r} was expected") def contains(validator, contains, instance, schema): if not validator.is_type(instance, "array"): return - if not any(validator.is_valid(element, contains) for element in instance): - yield ValidationError( - "None of %r are valid under the given schema" % (instance,) - ) + matches = 0 + min_contains = schema.get("minContains", 1) + max_contains = schema.get("maxContains", len(instance)) + + for each in instance: + if validator.evolve(schema=contains).is_valid(each): + matches += 1 + if matches > max_contains: + yield ValidationError( + "Too many items match the given schema " + f"(expected at most {max_contains})", + validator="maxContains", + validator_value=max_contains, + ) + return + + if matches < min_contains: + if not matches: + yield ValidationError( + f"{instance!r} does not contain items " + "matching the given schema", + ) + else: + yield ValidationError( + "Too few items match the given schema (expected at least " + f"{min_contains} but only {matches} matched)", + validator="minContains", + validator_value=min_contains, + ) def exclusiveMinimum(validator, minimum, instance, schema): @@ -123,9 +144,8 @@ if instance <= minimum: yield ValidationError( - "%r is less than or equal to the minimum of %r" % ( - instance, minimum, - ), + f"{instance!r} is less than or equal to " + f"the minimum of {minimum!r}", ) @@ -135,9 +155,8 @@ if instance >= maximum: yield ValidationError( - "%r is greater than or equal to the maximum of %r" % ( - instance, maximum, - ), + f"{instance!r} is greater than or equal " + f"to the maximum of {maximum!r}", ) @@ -146,9 +165,8 @@ return if instance < minimum: - yield ValidationError( - "%r is less than the minimum of %r" % (instance, minimum) - ) + message = f"{instance!r} is less than the minimum of {minimum!r}" + yield ValidationError(message) def maximum(validator, maximum, instance, schema): @@ -156,9 +174,8 @@ return if instance > maximum: - yield ValidationError( - "%r is greater than the maximum of %r" % (instance, maximum) - ) + message = f"{instance!r} is greater than the maximum of {maximum!r}" + yield ValidationError(message) def multipleOf(validator, dB, instance, schema): @@ -167,39 +184,52 @@ if isinstance(dB, float): quotient = instance / dB - failed = int(quotient) != quotient + try: + failed = int(quotient) != quotient + except OverflowError: + # When `instance` is large and `dB` is less than one, + # quotient can overflow to infinity; and then casting to int + # raises an error. + # + # In this case we fall back to Fraction logic, which is + # exact and cannot overflow. The performance is also + # acceptable: we try the fast all-float option first, and + # we know that fraction(dB) can have at most a few hundred + # digits in each part. The worst-case slowdown is therefore + # for already-slow enormous integers or Decimals. + failed = (Fraction(instance) / Fraction(dB)).denominator != 1 else: failed = instance % dB if failed: - yield ValidationError("%r is not a multiple of %r" % (instance, dB)) + yield ValidationError(f"{instance!r} is not a multiple of {dB}") def minItems(validator, mI, instance, schema): if validator.is_type(instance, "array") and len(instance) < mI: - yield ValidationError("%r is too short" % (instance,)) + yield ValidationError(f"{instance!r} is too short") def maxItems(validator, mI, instance, schema): if validator.is_type(instance, "array") and len(instance) > mI: - yield ValidationError("%r is too long" % (instance,)) + yield ValidationError(f"{instance!r} is too long") def uniqueItems(validator, uI, instance, schema): if ( - uI and - validator.is_type(instance, "array") and - not uniq(instance) + uI + and validator.is_type(instance, "array") + and not uniq(instance) ): - yield ValidationError("%r has non-unique elements" % (instance,)) + yield ValidationError(f"{instance!r} has non-unique elements") def pattern(validator, patrn, instance, schema): if ( - validator.is_type(instance, "string") and - not re.search(patrn, instance) + validator.is_type(instance, "string") + and not re.search(patrn, instance) ): - yield ValidationError("%r does not match %r" % (instance, patrn)) + yield ValidationError(f"{instance!r} does not match {patrn!r}") def format(validator, format, instance, schema): @@ -212,80 +242,99 @@ def minLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) < mL: - yield ValidationError("%r is too short" % (instance,)) + yield ValidationError(f"{instance!r} is too short") def maxLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) > mL: - yield ValidationError("%r is too long" % (instance,)) + yield ValidationError(f"{instance!r} is too long") -def dependencies(validator, dependencies, instance, schema): +def dependentRequired(validator, dependentRequired, instance, schema): if not validator.is_type(instance, "object"): return - for property, dependency in iteritems(dependencies): + for property, dependency in dependentRequired.items(): if property not in instance: continue - if validator.is_type(dependency, "array"): - for each in dependency: - if each not in instance: - message = "%r is a dependency of %r" - yield ValidationError(message % (each, property)) - else: - for error in validator.descend( - instance, dependency, schema_path=property, - ): - yield error + for each in dependency: + if each not in instance: + message = f"{each!r} is a dependency of {property!r}" + yield ValidationError(message) + + +def dependentSchemas(validator, dependentSchemas, instance, schema): + if not validator.is_type(instance, "object"): + return + + for property, dependency in dependentSchemas.items(): + if property not in instance: + continue + yield from validator.descend( + instance, dependency, schema_path=property, + ) def enum(validator, enums, instance, schema): if instance == 0 or instance == 1: unbooled = unbool(instance) if all(unbooled != unbool(each) for each in enums): - yield ValidationError("%r is not one of %r" % (instance, enums)) + yield ValidationError(f"{instance!r} is not one of {enums!r}") elif instance not in enums: - yield ValidationError("%r is not one of %r" % (instance, enums)) + yield ValidationError(f"{instance!r} is not one of {enums!r}") def ref(validator, ref, instance, schema): resolve = getattr(validator.resolver, "resolve", None) if resolve is None: with validator.resolver.resolving(ref) as resolved: - for error in validator.descend(instance, resolved): - yield error + yield from validator.descend(instance, resolved) else: scope, resolved = validator.resolver.resolve(ref) validator.resolver.push_scope(scope) try: - for error in validator.descend(instance, resolved): - yield error + yield from validator.descend(instance, resolved) finally: validator.resolver.pop_scope() +def dynamicRef(validator, dynamicRef, instance, schema): + _, fragment = urldefrag(dynamicRef) + + for url in validator.resolver._scopes_stack: + lookup_url = urljoin(url, dynamicRef) + with validator.resolver.resolving(lookup_url) as subschema: + if ("$dynamicAnchor" in subschema + and fragment == subschema["$dynamicAnchor"]): + yield from validator.descend(instance, subschema) + break + else: + with validator.resolver.resolving(dynamicRef) as subschema: + yield from validator.descend(instance, subschema) + + def type(validator, types, instance, schema): types = ensure_list(types) if not any(validator.is_type(instance, type) for type in types): - yield ValidationError(types_msg(instance, types)) + reprs = ", ".join(repr(type) for type in types) + yield ValidationError(f"{instance!r} is not of type {reprs}") def properties(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return - for property, subschema in iteritems(properties): + for property, subschema in properties.items(): if property in instance: - for error in validator.descend( + yield from validator.descend( instance[property], subschema, path=property, schema_path=property, - ): - yield error + ) def required(validator, required, instance, schema): @@ -293,27 +342,24 @@ return for property in required: if property not in instance: - yield ValidationError("%r is a required property" % property) + yield ValidationError(f"{property!r} is a required property") def minProperties(validator, mP, instance, schema): if validator.is_type(instance, "object") and len(instance) < mP: - yield ValidationError( - "%r does not have enough properties" % (instance,) - ) + yield ValidationError(f"{instance!r} does not have enough properties") def maxProperties(validator, mP, instance, schema): if not validator.is_type(instance, "object"): return if validator.is_type(instance, "object") and len(instance) > mP: - yield ValidationError("%r has too many properties" % (instance,)) + yield ValidationError(f"{instance!r} has too many properties") def allOf(validator, allOf, instance, schema): for index, subschema in enumerate(allOf): - for error in validator.descend(instance, subschema, schema_path=index): - yield error + yield from validator.descend(instance, subschema, schema_path=index) def anyOf(validator, anyOf, instance, schema): @@ -325,7 +371,7 @@ all_errors.extend(errs) else: yield ValidationError( - "%r is not valid under any of the given schemas" % (instance,), + f"{instance!r} is not valid under any of the given schemas", context=all_errors, ) @@ -341,33 +387,81 @@ all_errors.extend(errs) else: yield ValidationError( - "%r is not valid under any of the given schemas" % (instance,), + f"{instance!r} is not valid under any of the given schemas", context=all_errors, ) - more_valid = [s for i, s in subschemas if validator.is_valid(instance, s)] + more_valid = [ + each for _, each in subschemas + if validator.evolve(schema=each).is_valid(instance) + ] if more_valid: more_valid.append(first_valid) reprs = ", ".join(repr(schema) for schema in more_valid) - yield ValidationError( - "%r is valid under each of %s" % (instance, reprs) - ) + yield ValidationError(f"{instance!r} is valid under each of {reprs}") def not_(validator, not_schema, instance, schema): - if validator.is_valid(instance, not_schema): - yield ValidationError( - "%r is not allowed for %r" % (not_schema, instance) - ) + if validator.evolve(schema=not_schema).is_valid(instance): + message = f"{instance!r} should not be valid under {not_schema!r}" + yield ValidationError(message) def if_(validator, if_schema, instance, schema): - if validator.is_valid(instance, if_schema): - if u"then" in schema: - then = schema[u"then"] - for error in validator.descend(instance, then, schema_path="then"): - yield error - elif u"else" in schema: - else_ = schema[u"else"] - for error in validator.descend(instance, else_, schema_path="else"): - yield error + if validator.evolve(schema=if_schema).is_valid(instance): + if "then" in schema: + then = schema["then"] + yield from validator.descend(instance, then, schema_path="then") + elif "else" in schema: + else_ = schema["else"] + yield from validator.descend(instance, else_, schema_path="else") + + +def unevaluatedItems(validator, unevaluatedItems, instance, schema): + if not validator.is_type(instance, "array"): + return + evaluated_item_indexes = find_evaluated_item_indexes_by_schema( + validator, instance, schema, + ) + unevaluated_items = [ + item for index, item in enumerate(instance) + if index not in evaluated_item_indexes + ] + if unevaluated_items: + error = "Unevaluated items are not allowed (%s %s unexpected)" + yield ValidationError(error % extras_msg(unevaluated_items)) + + +def unevaluatedProperties(validator, unevaluatedProperties, instance, schema): + if not validator.is_type(instance, "object"): + return + evaluated_property_keys = find_evaluated_property_keys_by_schema( + validator, instance, schema, + ) + unevaluated_property_keys = [] + for property in instance: + if property not in evaluated_property_keys: + for _ in validator.descend( + instance[property], + unevaluatedProperties, + path=property, + schema_path=property, + ): + unevaluated_property_keys.append(property) + + if unevaluated_property_keys: + error = "Unevaluated properties are not allowed (%s %s unexpected)" + yield ValidationError(error % extras_msg(unevaluated_property_keys)) + + +def prefixItems(validator, prefixItems, instance, schema): + if not validator.is_type(instance, "array"): + return + + for (index, item), subschema in zip(enumerate(instance), prefixItems): + yield from validator.descend( + instance=item, + schema=subschema, + schema_path=index, + path=index, + ) diff -Nru python-jsonschema-3.2.0/jsonschema/validators.py python-jsonschema-4.6.0/jsonschema/validators.py --- python-jsonschema-3.2.0/jsonschema/validators.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/jsonschema/validators.py 2022-06-01 20:26:26.000000000 +0000 @@ -1,105 +1,63 @@ """ Creation and extension of validators, with implementations for existing drafts. """ -from __future__ import division +from __future__ import annotations +from collections import deque +from collections.abc import Sequence +from functools import lru_cache +from urllib.parse import unquote, urldefrag, urljoin, urlsplit +from urllib.request import urlopen from warnings import warn import contextlib import json -import numbers +import reprlib +import typing +import warnings -from six import add_metaclass +import attr from jsonschema import ( + _format, _legacy_validators, _types, _utils, _validators, exceptions, ) -from jsonschema.compat import ( - Sequence, - int_types, - iteritems, - lru_cache, - str_types, - unquote, - urldefrag, - urljoin, - urlopen, - urlsplit, -) - -# Sigh. https://gitlab.com/pycqa/flake8/issues/280 -# https://github.com/pyga/ebb-lint/issues/7 -# Imported for backwards compatibility. -from jsonschema.exceptions import ErrorTree -ErrorTree - - -class _DontDoThat(Exception): - """ - Raised when a Validators with non-default type checker is misused. - - Asking one for DEFAULT_TYPES doesn't make sense, since type checkers - exist for the unrepresentable cases where DEFAULT_TYPES can't - represent the type relationship. - """ - - def __str__(self): - return "DEFAULT_TYPES cannot be used on Validators using TypeCheckers" - - -validators = {} -meta_schemas = _utils.URIDict() - - -def _generate_legacy_type_checks(types=()): - """ - Generate newer-style type checks out of JSON-type-name-to-type mappings. - - Arguments: - types (dict): +_VALIDATORS: dict[str, typing.Any] = {} +_META_SCHEMAS = _utils.URIDict() +_VOCABULARIES: list[tuple[str, typing.Any]] = [] - A mapping of type names to their Python types - Returns: - - A dictionary of definitions to pass to `TypeChecker` - """ - types = dict(types) - - def gen_type_check(pytypes): - pytypes = _utils.flatten(pytypes) - - def type_check(checker, instance): - if isinstance(instance, bool): - if bool not in pytypes: - return False - return isinstance(instance, pytypes) - - return type_check - - definitions = {} - for typename, pytypes in iteritems(types): - definitions[typename] = gen_type_check(pytypes) - - return definitions - - -_DEPRECATED_DEFAULT_TYPES = { - u"array": list, - u"boolean": bool, - u"integer": int_types, - u"null": type(None), - u"number": numbers.Number, - u"object": dict, - u"string": str_types, -} -_TYPE_CHECKER_FOR_DEPRECATED_DEFAULT_TYPES = _types.TypeChecker( - type_checkers=_generate_legacy_type_checks(_DEPRECATED_DEFAULT_TYPES), -) +def __getattr__(name): + if name == "ErrorTree": + warnings.warn( + "Importing ErrorTree from jsonschema.validators is deprecated. " + "Instead import it from jsonschema.exceptions.", + DeprecationWarning, + stacklevel=2, + ) + from jsonschema.exceptions import ErrorTree + return ErrorTree + elif name == "validators": + warnings.warn( + "Accessing jsonschema.validators.validators is deprecated. " + "Use jsonschema.validators.validator_for with a given schema.", + DeprecationWarning, + stacklevel=2, + ) + return _VALIDATORS + elif name == "meta_schemas": + warnings.warn( + "Accessing jsonschema.validators.meta_schemas is deprecated. " + "Use jsonschema.validators.validator_for with a given schema.", + DeprecationWarning, + stacklevel=2, + ) + return _META_SCHEMAS + raise AttributeError(f"module {__name__} has no attribute {name}") def validates(version): @@ -117,63 +75,55 @@ Returns: - collections.Callable: + collections.abc.Callable: a class decorator to decorate the validator with the version """ def _validates(cls): - validators[version] = cls + _VALIDATORS[version] = cls meta_schema_id = cls.ID_OF(cls.META_SCHEMA) - if meta_schema_id: - meta_schemas[meta_schema_id] = cls + _META_SCHEMAS[meta_schema_id] = cls return cls return _validates -def _DEFAULT_TYPES(self): - if self._CREATED_WITH_DEFAULT_TYPES is None: - raise _DontDoThat() - - warn( - ( - "The DEFAULT_TYPES attribute is deprecated. " - "See the type checker attached to this validator instead." - ), - DeprecationWarning, - stacklevel=2, - ) - return self._DEFAULT_TYPES - - -class _DefaultTypesDeprecatingMetaClass(type): - DEFAULT_TYPES = property(_DEFAULT_TYPES) - - def _id_of(schema): + """ + Return the ID of a schema for recent JSON Schema drafts. + """ if schema is True or schema is False: - return u"" - return schema.get(u"$id", u"") + return "" + return schema.get("$id", "") + + +def _store_schema_list(): + if not _VOCABULARIES: + _VOCABULARIES.extend(_utils.load_schema("vocabularies").items()) + return [ + (id, validator.META_SCHEMA) for id, validator in _META_SCHEMAS.items() + ] + _VOCABULARIES def create( meta_schema, validators=(), version=None, - default_types=None, - type_checker=None, + type_checker=_types.draft202012_type_checker, + format_checker=_format.draft202012_format_checker, id_of=_id_of, + applicable_validators=lambda schema: schema.items(), ): """ Create a new validator class. Arguments: - meta_schema (collections.Mapping): + meta_schema (collections.abc.Mapping): the meta schema for the new validator class - validators (collections.Mapping): + validators (collections.abc.Mapping): a mapping from names to callables, where each callable will validate the schema property with the given name. @@ -201,107 +151,77 @@ If unprovided, a `jsonschema.TypeChecker` will be created with a set of default types typical of JSON Schema drafts. - default_types (collections.Mapping): + format_checker (jsonschema.FormatChecker): - .. deprecated:: 3.0.0 + a format checker, used when applying the :validator:`format` + validator. - Please use the type_checker argument instead. + If unprovided, a `jsonschema.FormatChecker` will be created + with a set of default formats typical of JSON Schema drafts. - If set, it provides mappings of JSON types to Python types - that will be converted to functions and redefined in this - object's `jsonschema.TypeChecker`. - - id_of (collections.Callable): + id_of (collections.abc.Callable): A function that given a schema, returns its ID. + applicable_validators (collections.abc.Callable): + + A function that given a schema, returns the list of applicable + validators (names and callables) which will be called to + validate the instance. + Returns: - a new `jsonschema.IValidator` class + a new `jsonschema.protocols.Validator` class """ + # preemptively don't shadow the `Validator.format_checker` local + format_checker_arg = format_checker - if default_types is not None: - if type_checker is not None: - raise TypeError( - "Do not specify default_types when providing a type checker.", - ) - _created_with_default_types = True - warn( - ( - "The default_types argument is deprecated. " - "Use the type_checker argument instead." - ), - DeprecationWarning, - stacklevel=2, - ) - type_checker = _types.TypeChecker( - type_checkers=_generate_legacy_type_checks(default_types), - ) - else: - default_types = _DEPRECATED_DEFAULT_TYPES - if type_checker is None: - _created_with_default_types = False - type_checker = _TYPE_CHECKER_FOR_DEPRECATED_DEFAULT_TYPES - elif type_checker is _TYPE_CHECKER_FOR_DEPRECATED_DEFAULT_TYPES: - _created_with_default_types = False - else: - _created_with_default_types = None - - @add_metaclass(_DefaultTypesDeprecatingMetaClass) - class Validator(object): + @attr.s + class Validator: VALIDATORS = dict(validators) META_SCHEMA = dict(meta_schema) TYPE_CHECKER = type_checker + FORMAT_CHECKER = format_checker_arg ID_OF = staticmethod(id_of) - DEFAULT_TYPES = property(_DEFAULT_TYPES) - _DEFAULT_TYPES = dict(default_types) - _CREATED_WITH_DEFAULT_TYPES = _created_with_default_types - - def __init__( - self, - schema, - types=(), - resolver=None, - format_checker=None, - ): - if types: - warn( - ( - "The types argument is deprecated. Provide " - "a type_checker to jsonschema.validators.extend " - "instead." - ), - DeprecationWarning, - stacklevel=2, + schema = attr.ib(repr=reprlib.repr) + resolver = attr.ib(default=None, repr=False) + format_checker = attr.ib(default=None) + evolve = attr.evolve + + def __attrs_post_init__(self): + if self.resolver is None: + self.resolver = RefResolver.from_schema( + self.schema, + id_of=id_of, ) - self.TYPE_CHECKER = self.TYPE_CHECKER.redefine_many( - _generate_legacy_type_checks(types), - ) - - if resolver is None: - resolver = RefResolver.from_schema(schema, id_of=id_of) - - self.resolver = resolver - self.format_checker = format_checker - self.schema = schema - @classmethod def check_schema(cls, schema): for error in cls(cls.META_SCHEMA).iter_errors(schema): raise exceptions.SchemaError.create_from(error) def iter_errors(self, instance, _schema=None): - if _schema is None: + if _schema is not None: + warnings.warn( + ( + "Passing a schema to Validator.iter_errors " + "is deprecated and will be removed in a future " + "release. Call validator.evolve(schema=new_schema)." + "iter_errors(...) instead." + ), + DeprecationWarning, + stacklevel=2, + ) + else: _schema = self.schema if _schema is True: return elif _schema is False: yield exceptions.ValidationError( - "False schema does not allow %r" % (instance,), + f"False schema does not allow {instance!r}", validator=None, validator_value=None, instance=instance, @@ -313,13 +233,7 @@ if scope: self.resolver.push_scope(scope) try: - ref = _schema.get(u"$ref") - if ref is not None: - validators = [(u"$ref", ref)] - else: - validators = iteritems(_schema) - - for k, v in validators: + for k, v in applicable_validators(_schema): validator = self.VALIDATORS.get(k) if validator is None: continue @@ -333,7 +247,7 @@ instance=instance, schema=_schema, ) - if k != u"$ref": + if k not in {"if", "$ref"}: error.schema_path.appendleft(k) yield error finally: @@ -341,7 +255,7 @@ self.resolver.pop_scope() def descend(self, instance, schema, path=None, schema_path=None): - for error in self.iter_errors(instance, schema): + for error in self.evolve(schema=schema).iter_errors(instance): if path is not None: error.path.appendleft(path) if schema_path is not None: @@ -359,27 +273,47 @@ raise exceptions.UnknownType(type, instance, self.schema) def is_valid(self, instance, _schema=None): - error = next(self.iter_errors(instance, _schema), None) + if _schema is not None: + warnings.warn( + ( + "Passing a schema to Validator.is_valid is deprecated " + "and will be removed in a future release. Call " + "validator.evolve(schema=new_schema).is_valid(...) " + "instead." + ), + DeprecationWarning, + stacklevel=2, + ) + self = self.evolve(schema=_schema) + + error = next(self.iter_errors(instance), None) return error is None if version is not None: + safe = version.title().replace(" ", "").replace("-", "") + Validator.__name__ = Validator.__qualname__ = f"{safe}Validator" Validator = validates(version)(Validator) - Validator.__name__ = version.title().replace(" ", "") + "Validator" return Validator -def extend(validator, validators=(), version=None, type_checker=None): +def extend( + validator, + validators=(), + version=None, + type_checker=None, + format_checker=None, +): """ Create a new validator class by extending an existing one. Arguments: - validator (jsonschema.IValidator): + validator (jsonschema.protocols.Validator): an existing validator class - validators (collections.Mapping): + validators (collections.abc.Mapping): a mapping of new validator callables to extend with, whose structure is as in `create`. @@ -405,11 +339,20 @@ a type checker, used when applying the :validator:`type` validator. If unprovided, the type checker of the extended - `jsonschema.IValidator` will be carried along.` + `jsonschema.protocols.Validator` will be carried along. + + format_checker (jsonschema.FormatChecker): + + a format checker, used when applying the :validator:`format` + validator. + + If unprovided, the format checker of the extended + `jsonschema.protocols.Validator` will be carried along. Returns: - a new `jsonschema.IValidator` class extending the one provided + a new `jsonschema.protocols.Validator` class extending the one + provided .. note:: Meta Schemas @@ -427,17 +370,14 @@ if type_checker is None: type_checker = validator.TYPE_CHECKER - elif validator._CREATED_WITH_DEFAULT_TYPES: - raise TypeError( - "Cannot extend a validator created with default_types " - "with a type_checker. Update the validator to use a " - "type_checker when created." - ) + if format_checker is None: + format_checker = validator.FORMAT_CHECKER return create( meta_schema=validator.META_SCHEMA, validators=all_validators, version=version, type_checker=type_checker, + format_checker=format_checker, id_of=validator.ID_OF, ) @@ -445,148 +385,247 @@ Draft3Validator = create( meta_schema=_utils.load_schema("draft3"), validators={ - u"$ref": _validators.ref, - u"additionalItems": _validators.additionalItems, - u"additionalProperties": _validators.additionalProperties, - u"dependencies": _legacy_validators.dependencies_draft3, - u"disallow": _legacy_validators.disallow_draft3, - u"divisibleBy": _validators.multipleOf, - u"enum": _validators.enum, - u"extends": _legacy_validators.extends_draft3, - u"format": _validators.format, - u"items": _legacy_validators.items_draft3_draft4, - u"maxItems": _validators.maxItems, - u"maxLength": _validators.maxLength, - u"maximum": _legacy_validators.maximum_draft3_draft4, - u"minItems": _validators.minItems, - u"minLength": _validators.minLength, - u"minimum": _legacy_validators.minimum_draft3_draft4, - u"pattern": _validators.pattern, - u"patternProperties": _validators.patternProperties, - u"properties": _legacy_validators.properties_draft3, - u"type": _legacy_validators.type_draft3, - u"uniqueItems": _validators.uniqueItems, + "$ref": _validators.ref, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "dependencies": _legacy_validators.dependencies_draft3, + "disallow": _legacy_validators.disallow_draft3, + "divisibleBy": _validators.multipleOf, + "enum": _validators.enum, + "extends": _legacy_validators.extends_draft3, + "format": _validators.format, + "items": _legacy_validators.items_draft3_draft4, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maximum": _legacy_validators.maximum_draft3_draft4, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minimum": _legacy_validators.minimum_draft3_draft4, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "properties": _legacy_validators.properties_draft3, + "type": _legacy_validators.type_draft3, + "uniqueItems": _validators.uniqueItems, }, type_checker=_types.draft3_type_checker, + format_checker=_format.draft3_format_checker, version="draft3", - id_of=lambda schema: schema.get(u"id", ""), + id_of=lambda schema: schema.get("id", ""), + applicable_validators=_legacy_validators.ignore_ref_siblings, ) Draft4Validator = create( meta_schema=_utils.load_schema("draft4"), validators={ - u"$ref": _validators.ref, - u"additionalItems": _validators.additionalItems, - u"additionalProperties": _validators.additionalProperties, - u"allOf": _validators.allOf, - u"anyOf": _validators.anyOf, - u"dependencies": _validators.dependencies, - u"enum": _validators.enum, - u"format": _validators.format, - u"items": _legacy_validators.items_draft3_draft4, - u"maxItems": _validators.maxItems, - u"maxLength": _validators.maxLength, - u"maxProperties": _validators.maxProperties, - u"maximum": _legacy_validators.maximum_draft3_draft4, - u"minItems": _validators.minItems, - u"minLength": _validators.minLength, - u"minProperties": _validators.minProperties, - u"minimum": _legacy_validators.minimum_draft3_draft4, - u"multipleOf": _validators.multipleOf, - u"not": _validators.not_, - u"oneOf": _validators.oneOf, - u"pattern": _validators.pattern, - u"patternProperties": _validators.patternProperties, - u"properties": _validators.properties, - u"required": _validators.required, - u"type": _validators.type, - u"uniqueItems": _validators.uniqueItems, + "$ref": _validators.ref, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "allOf": _validators.allOf, + "anyOf": _validators.anyOf, + "dependencies": _legacy_validators.dependencies_draft4_draft6_draft7, + "enum": _validators.enum, + "format": _validators.format, + "items": _legacy_validators.items_draft3_draft4, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maxProperties": _validators.maxProperties, + "maximum": _legacy_validators.maximum_draft3_draft4, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minProperties": _validators.minProperties, + "minimum": _legacy_validators.minimum_draft3_draft4, + "multipleOf": _validators.multipleOf, + "not": _validators.not_, + "oneOf": _validators.oneOf, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "properties": _validators.properties, + "required": _validators.required, + "type": _validators.type, + "uniqueItems": _validators.uniqueItems, }, type_checker=_types.draft4_type_checker, + format_checker=_format.draft4_format_checker, version="draft4", - id_of=lambda schema: schema.get(u"id", ""), + id_of=lambda schema: schema.get("id", ""), + applicable_validators=_legacy_validators.ignore_ref_siblings, ) Draft6Validator = create( meta_schema=_utils.load_schema("draft6"), validators={ - u"$ref": _validators.ref, - u"additionalItems": _validators.additionalItems, - u"additionalProperties": _validators.additionalProperties, - u"allOf": _validators.allOf, - u"anyOf": _validators.anyOf, - u"const": _validators.const, - u"contains": _validators.contains, - u"dependencies": _validators.dependencies, - u"enum": _validators.enum, - u"exclusiveMaximum": _validators.exclusiveMaximum, - u"exclusiveMinimum": _validators.exclusiveMinimum, - u"format": _validators.format, - u"items": _validators.items, - u"maxItems": _validators.maxItems, - u"maxLength": _validators.maxLength, - u"maxProperties": _validators.maxProperties, - u"maximum": _validators.maximum, - u"minItems": _validators.minItems, - u"minLength": _validators.minLength, - u"minProperties": _validators.minProperties, - u"minimum": _validators.minimum, - u"multipleOf": _validators.multipleOf, - u"not": _validators.not_, - u"oneOf": _validators.oneOf, - u"pattern": _validators.pattern, - u"patternProperties": _validators.patternProperties, - u"properties": _validators.properties, - u"propertyNames": _validators.propertyNames, - u"required": _validators.required, - u"type": _validators.type, - u"uniqueItems": _validators.uniqueItems, + "$ref": _validators.ref, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "allOf": _validators.allOf, + "anyOf": _validators.anyOf, + "const": _validators.const, + "contains": _legacy_validators.contains_draft6_draft7, + "dependencies": _legacy_validators.dependencies_draft4_draft6_draft7, + "enum": _validators.enum, + "exclusiveMaximum": _validators.exclusiveMaximum, + "exclusiveMinimum": _validators.exclusiveMinimum, + "format": _validators.format, + "items": _legacy_validators.items_draft6_draft7_draft201909, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maxProperties": _validators.maxProperties, + "maximum": _validators.maximum, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minProperties": _validators.minProperties, + "minimum": _validators.minimum, + "multipleOf": _validators.multipleOf, + "not": _validators.not_, + "oneOf": _validators.oneOf, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "properties": _validators.properties, + "propertyNames": _validators.propertyNames, + "required": _validators.required, + "type": _validators.type, + "uniqueItems": _validators.uniqueItems, }, type_checker=_types.draft6_type_checker, + format_checker=_format.draft6_format_checker, version="draft6", + applicable_validators=_legacy_validators.ignore_ref_siblings, ) Draft7Validator = create( meta_schema=_utils.load_schema("draft7"), validators={ - u"$ref": _validators.ref, - u"additionalItems": _validators.additionalItems, - u"additionalProperties": _validators.additionalProperties, - u"allOf": _validators.allOf, - u"anyOf": _validators.anyOf, - u"const": _validators.const, - u"contains": _validators.contains, - u"dependencies": _validators.dependencies, - u"enum": _validators.enum, - u"exclusiveMaximum": _validators.exclusiveMaximum, - u"exclusiveMinimum": _validators.exclusiveMinimum, - u"format": _validators.format, - u"if": _validators.if_, - u"items": _validators.items, - u"maxItems": _validators.maxItems, - u"maxLength": _validators.maxLength, - u"maxProperties": _validators.maxProperties, - u"maximum": _validators.maximum, - u"minItems": _validators.minItems, - u"minLength": _validators.minLength, - u"minProperties": _validators.minProperties, - u"minimum": _validators.minimum, - u"multipleOf": _validators.multipleOf, - u"oneOf": _validators.oneOf, - u"not": _validators.not_, - u"pattern": _validators.pattern, - u"patternProperties": _validators.patternProperties, - u"properties": _validators.properties, - u"propertyNames": _validators.propertyNames, - u"required": _validators.required, - u"type": _validators.type, - u"uniqueItems": _validators.uniqueItems, + "$ref": _validators.ref, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "allOf": _validators.allOf, + "anyOf": _validators.anyOf, + "const": _validators.const, + "contains": _legacy_validators.contains_draft6_draft7, + "dependencies": _legacy_validators.dependencies_draft4_draft6_draft7, + "enum": _validators.enum, + "exclusiveMaximum": _validators.exclusiveMaximum, + "exclusiveMinimum": _validators.exclusiveMinimum, + "format": _validators.format, + "if": _validators.if_, + "items": _legacy_validators.items_draft6_draft7_draft201909, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maxProperties": _validators.maxProperties, + "maximum": _validators.maximum, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minProperties": _validators.minProperties, + "minimum": _validators.minimum, + "multipleOf": _validators.multipleOf, + "not": _validators.not_, + "oneOf": _validators.oneOf, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "properties": _validators.properties, + "propertyNames": _validators.propertyNames, + "required": _validators.required, + "type": _validators.type, + "uniqueItems": _validators.uniqueItems, }, type_checker=_types.draft7_type_checker, + format_checker=_format.draft7_format_checker, version="draft7", + applicable_validators=_legacy_validators.ignore_ref_siblings, +) + +Draft201909Validator = create( + meta_schema=_utils.load_schema("draft2019-09"), + validators={ + "$recursiveRef": _legacy_validators.recursiveRef, + "$ref": _validators.ref, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "allOf": _validators.allOf, + "anyOf": _validators.anyOf, + "const": _validators.const, + "contains": _validators.contains, + "dependentRequired": _validators.dependentRequired, + "dependentSchemas": _validators.dependentSchemas, + "enum": _validators.enum, + "exclusiveMaximum": _validators.exclusiveMaximum, + "exclusiveMinimum": _validators.exclusiveMinimum, + "format": _validators.format, + "if": _validators.if_, + "items": _legacy_validators.items_draft6_draft7_draft201909, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maxProperties": _validators.maxProperties, + "maximum": _validators.maximum, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minProperties": _validators.minProperties, + "minimum": _validators.minimum, + "multipleOf": _validators.multipleOf, + "not": _validators.not_, + "oneOf": _validators.oneOf, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "properties": _validators.properties, + "propertyNames": _validators.propertyNames, + "required": _validators.required, + "type": _validators.type, + "unevaluatedItems": _validators.unevaluatedItems, + "unevaluatedProperties": _validators.unevaluatedProperties, + "uniqueItems": _validators.uniqueItems, + }, + type_checker=_types.draft201909_type_checker, + format_checker=_format.draft201909_format_checker, + version="draft2019-09", ) -_LATEST_VERSION = Draft7Validator +Draft202012Validator = create( + meta_schema=_utils.load_schema("draft2020-12"), + validators={ + "$dynamicRef": _validators.dynamicRef, + "$ref": _validators.ref, + "additionalItems": _validators.additionalItems, + "additionalProperties": _validators.additionalProperties, + "allOf": _validators.allOf, + "anyOf": _validators.anyOf, + "const": _validators.const, + "contains": _validators.contains, + "dependentRequired": _validators.dependentRequired, + "dependentSchemas": _validators.dependentSchemas, + "enum": _validators.enum, + "exclusiveMaximum": _validators.exclusiveMaximum, + "exclusiveMinimum": _validators.exclusiveMinimum, + "format": _validators.format, + "if": _validators.if_, + "items": _validators.items, + "maxItems": _validators.maxItems, + "maxLength": _validators.maxLength, + "maxProperties": _validators.maxProperties, + "maximum": _validators.maximum, + "minItems": _validators.minItems, + "minLength": _validators.minLength, + "minProperties": _validators.minProperties, + "minimum": _validators.minimum, + "multipleOf": _validators.multipleOf, + "not": _validators.not_, + "oneOf": _validators.oneOf, + "pattern": _validators.pattern, + "patternProperties": _validators.patternProperties, + "prefixItems": _validators.prefixItems, + "properties": _validators.properties, + "propertyNames": _validators.propertyNames, + "required": _validators.required, + "type": _validators.type, + "unevaluatedItems": _validators.unevaluatedItems, + "unevaluatedProperties": _validators.unevaluatedProperties, + "uniqueItems": _validators.uniqueItems, + }, + type_checker=_types.draft202012_type_checker, + format_checker=_format.draft202012_format_checker, + version="draft2020-12", +) + +_LATEST_VERSION = Draft202012Validator class RefResolver(object): @@ -653,10 +692,7 @@ self.handlers = dict(handlers) self._scopes_stack = [base_uri] - self.store = _utils.URIDict( - (id, validator.META_SCHEMA) - for id, validator in iteritems(meta_schemas) - ) + self.store = _utils.URIDict(_store_schema_list()) self.store.update(store) self.store[base_uri] = referrer @@ -708,7 +744,7 @@ raise exceptions.RefResolutionError( "Failed to pop the scope from an empty stack. " "`pop_scope()` should only be called once for every " - "`push_scope()`" + "`push_scope()`", ) @property @@ -731,6 +767,12 @@ """ Temporarily enter the given scope for the duration of the context. """ + warnings.warn( + "jsonschema.RefResolver.in_scope is deprecated and will be " + "removed in a future release.", + DeprecationWarning, + stacklevel=3, + ) self.push_scope(scope) try: yield @@ -758,11 +800,44 @@ finally: self.pop_scope() + def _find_in_referrer(self, key): + return self._get_subschemas_cache()[key] + + @lru_cache() # noqa: B019 + def _get_subschemas_cache(self): + cache = {key: [] for key in _SUBSCHEMAS_KEYWORDS} + for keyword, subschema in _search_schema( + self.referrer, _match_subschema_keywords, + ): + cache[keyword].append(subschema) + return cache + + @lru_cache() # noqa: B019 + def _find_in_subschemas(self, url): + subschemas = self._get_subschemas_cache()["$id"] + if not subschemas: + return None + uri, fragment = urldefrag(url) + for subschema in subschemas: + target_uri = self._urljoin_cache( + self.resolution_scope, subschema["$id"], + ) + if target_uri.rstrip("/") == uri.rstrip("/"): + if fragment: + subschema = self.resolve_fragment(subschema, fragment) + return url, subschema + return None + def resolve(self, ref): """ Resolve the given reference. """ - url = self._urljoin_cache(self.resolution_scope, ref) + url = self._urljoin_cache(self.resolution_scope, ref).rstrip("/") + + match = self._find_in_subschemas(url) + if match is not None: + return match + return url, self._remote_cache(url) def resolve_from_url(self, url): @@ -795,11 +870,31 @@ a URI fragment to resolve within it """ - fragment = fragment.lstrip(u"/") - parts = unquote(fragment).split(u"/") if fragment else [] + fragment = fragment.lstrip("/") + + if not fragment: + return document + if document is self.referrer: + find = self._find_in_referrer + else: + + def find(key): + yield from _search_schema(document, _match_keyword(key)) + + for keyword in ["$anchor", "$dynamicAnchor"]: + for subschema in find(keyword): + if fragment == subschema[keyword]: + return subschema + for keyword in ["id", "$id"]: + for subschema in find(keyword): + if "#" + fragment == subschema[keyword]: + return subschema + + # Resolve via path + parts = unquote(fragment).split("/") if fragment else [] for part in parts: - part = part.replace(u"~1", u"/").replace(u"~0", u"~") + part = part.replace("~1", "/").replace("~0", "~") if isinstance(document, Sequence): # Array indexes should be turned into integers @@ -811,7 +906,7 @@ document = document[part] except (TypeError, LookupError): raise exceptions.RefResolutionError( - "Unresolvable JSON pointer: %r" % fragment + f"Unresolvable JSON pointer: {fragment!r}", ) return document @@ -854,7 +949,7 @@ if scheme in self.handlers: result = self.handlers[scheme](uri) - elif scheme in [u"http", u"https"] and requests: + elif scheme in ["http", "https"] and requests: # Requests has support for detecting the correct encoding of # json over http result = requests.get(uri).json() @@ -868,6 +963,35 @@ return result +_SUBSCHEMAS_KEYWORDS = ("$id", "id", "$anchor", "$dynamicAnchor") + + +def _match_keyword(keyword): + + def matcher(value): + if keyword in value: + yield value + + return matcher + + +def _match_subschema_keywords(value): + for keyword in _SUBSCHEMAS_KEYWORDS: + if keyword in value: + yield keyword, value + + +def _search_schema(schema, matcher): + """Breadth-first search routine.""" + values = deque([schema]) + while values: + value = values.pop() + if not isinstance(value, dict): + continue + yield from matcher(value) + values.extendleft(value.values()) + + def validate(instance, schema, cls=None, *args, **kwargs): """ Validate an instance under the given schema. @@ -883,7 +1007,7 @@ If you know you have a valid schema already, especially if you intend to validate multiple instances with the same schema, you - likely would prefer using the `IValidator.validate` method directly + likely would prefer using the `Validator.validate` method directly on a specific validator (e.g. ``Draft7Validator.validate``). @@ -897,7 +1021,7 @@ The schema to validate with - cls (IValidator): + cls (Validator): The class that will be used to validate the instance. @@ -943,7 +1067,7 @@ Arguments: - schema (collections.Mapping or bool): + schema (collections.abc.Mapping or bool): the schema to look at @@ -955,9 +1079,9 @@ If unprovided, the default is to return the latest supported draft. """ - if schema is True or schema is False or u"$schema" not in schema: + if schema is True or schema is False or "$schema" not in schema: return default - if schema[u"$schema"] not in meta_schemas: + if schema["$schema"] not in _META_SCHEMAS: warn( ( "The metaschema specified by $schema was not found. " @@ -967,4 +1091,4 @@ DeprecationWarning, stacklevel=2, ) - return meta_schemas.get(schema[u"$schema"], _LATEST_VERSION) + return _META_SCHEMAS.get(schema["$schema"], _LATEST_VERSION) diff -Nru python-jsonschema-3.2.0/MANIFEST.in python-jsonschema-4.6.0/MANIFEST.in --- python-jsonschema-3.2.0/MANIFEST.in 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/MANIFEST.in 2022-06-01 20:26:26.000000000 +0000 @@ -1,4 +1,5 @@ +graft json include *.rst include COPYING +include pyproject.toml include tox.ini -recursive-include json * diff -Nru python-jsonschema-3.2.0/.pre-commit-config.yaml python-jsonschema-4.6.0/.pre-commit-config.yaml --- python-jsonschema-3.2.0/.pre-commit-config.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.pre-commit-config.yaml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,21 @@ +exclude: json/ + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.2.0 + hooks: + - id: check-ast + - id: check-docstring-first + - id: check-json + - id: check-toml + - id: check-vcs-permalinks + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + args: [--fix, lf] + - id: trailing-whitespace +- repo: https://github.com/PyCQA/isort + rev: 5.10.1 + hooks: + - id: isort diff -Nru python-jsonschema-3.2.0/.pre-commit-hooks.yaml python-jsonschema-4.6.0/.pre-commit-hooks.yaml --- python-jsonschema-3.2.0/.pre-commit-hooks.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.pre-commit-hooks.yaml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,6 @@ +- id: jsonschema + name: jsonschema + description: json schema validation + language: python + pass_filenames: false + entry: jsonschema diff -Nru python-jsonschema-3.2.0/pyproject.toml python-jsonschema-4.6.0/pyproject.toml --- python-jsonschema-3.2.0/pyproject.toml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/pyproject.toml 2022-06-01 20:26:26.000000000 +0000 @@ -1,8 +1,97 @@ [build-system] -requires = [ - # The minimum setuptools version is specific to the PEP 517 backend, - # and may be stricter than the version required in `setup.py` - "setuptools>=40.6.0", - "wheel", +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[tool.hatch.version] +source = "vcs" + +[project] +name = "jsonschema" +description = "An implementation of JSON Schema validation for Python" +readme = "README.rst" +requires-python = ">=3.7" +license = {text = "MIT"} +keywords = ["validation", "data validation", "jsonschema", "json"] +authors = [ + {email = "Julian+jsonschema@GrayVines.com"}, + {name = "Julian Berman"}, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dynamic = ["version"] + +dependencies = [ + "attrs>=17.4.0", + "pyrsistent>=0.14.0,!=0.17.0,!=0.17.1,!=0.17.2", + + "importlib_metadata;python_version<'3.8'", + "typing_extensions;python_version<'3.8'", + "importlib_resources>=1.4.0;python_version<'3.9'", +] + +[project.optional-dependencies] +format = [ + "fqdn", + "idna", + "isoduration", + "jsonpointer>1.13", + "rfc3339-validator", + "rfc3987", + "uri_template", + "webcolors>=1.11", +] +format_nongpl = [ + "fqdn", + "idna", + "isoduration", + "jsonpointer>1.13", + "rfc3339-validator", + "rfc3986-validator>0.1.0", + "uri_template", + "webcolors>=1.11", +] + +[project.scripts] +jsonschema = "jsonschema.cli:main" + +[project.urls] +homepage = "https://github.com/python-jsonschema/jsonschema" +documentation = "https://python-jsonschema.readthedocs.io/" +issues = "https://github.com/python-jsonschema/jsonschema/issues/" +funding = "https://github.com/sponsors/Julian" +tidelift = "https://tidelift.com/subscription/pkg/pypi-jsonschema?utm_source=pypi-jsonschema&utm_medium=referral&utm_campaign=pypi-link" +changelog = "https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst" +source = "https://github.com/python-jsonschema/jsonschema" + +[tool.isort] +from_first = true +include_trailing_comma = true +multi_line_output = 3 + +[tool.mypy] +ignore_missing_imports = true + +[tool.pydocstyle] +match = "(?!(test_|_|compat|cli)).*\\.py" # see PyCQA/pydocstyle#323 +add-select = [ + "D410", # Trailing whitespace plz +] +add-ignore = [ + "D107", # Hah, no + "D200", # 1-line docstrings don't need to be on one line + "D202", # One line is fine. + "D412", # Trailing whitespace plz + "D413", # No trailing whitespace plz ] -build-backend = "setuptools.build_meta" diff -Nru python-jsonschema-3.2.0/README.rst python-jsonschema-4.6.0/README.rst --- python-jsonschema-3.2.0/README.rst 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/README.rst 2022-06-01 20:26:26.000000000 +0000 @@ -2,7 +2,7 @@ jsonschema ========== -|PyPI| |Pythons| |Travis| |AppVeyor| |Codecov| |ReadTheDocs| +|PyPI| |Pythons| |CI| |ReadTheDocs| |Precommit| |Zenodo| .. |PyPI| image:: https://img.shields.io/pypi/v/jsonschema.svg :alt: PyPI version @@ -12,25 +12,24 @@ :alt: Supported Python versions :target: https://pypi.org/project/jsonschema/ -.. |Travis| image:: https://travis-ci.com/Julian/jsonschema.svg?branch=master - :alt: Travis build status - :target: https://travis-ci.com/Julian/jsonschema - -.. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/adtt0aiaihy6muyn/branch/master?svg=true - :alt: AppVeyor build status - :target: https://ci.appveyor.com/project/Julian/jsonschema - -.. |Codecov| image:: https://codecov.io/gh/Julian/jsonschema/branch/master/graph/badge.svg - :alt: Codecov Code coverage - :target: https://codecov.io/gh/Julian/jsonschema +.. |CI| image:: https://github.com/python-jsonschema/jsonschema/workflows/CI/badge.svg + :alt: Build status + :target: https://github.com/python-jsonschema/jsonschema/actions?query=workflow%3ACI .. |ReadTheDocs| image:: https://readthedocs.org/projects/python-jsonschema/badge/?version=stable&style=flat :alt: ReadTheDocs status :target: https://python-jsonschema.readthedocs.io/en/stable/ +.. |Precommit| image:: https://results.pre-commit.ci/badge/github/python-jsonschema/jsonschema/main.svg + :alt: pre-commit.ci status + :target: https://results.pre-commit.ci/latest/github/python-jsonschema/jsonschema/main -``jsonschema`` is an implementation of `JSON Schema `_ -for Python (supporting 2.7+ including Python 3). +.. |Zenodo| image:: https://zenodo.org/badge/3072629.svg + :target: https://zenodo.org/badge/latestdoi/3072629 + + +``jsonschema`` is an implementation of the `JSON Schema +`_ specification for Python. .. code-block:: python @@ -59,19 +58,23 @@ .. code-block:: bash - $ jsonschema -i sample.json sample.schema + $ jsonschema --instance sample.json sample.schema Features -------- -* Full support for +* Partial support for + `Draft 2020-12 `_ and + `Draft 2019-09 `_, + except for ``dynamicRef`` / ``recursiveRef`` and ``$vocabulary`` (in-progress). + Full support for `Draft 7 `_, `Draft 6 `_, `Draft 4 `_ and `Draft 3 `_ -* `Lazy validation `_ +* `Lazy validation `_ that can iteratively report *all* validation errors. * `Programmatic querying `_ @@ -88,33 +91,6 @@ $ pip install jsonschema -Demo ----- - -Try ``jsonschema`` interactively in this online demo: - -.. image:: https://user-images.githubusercontent.com/1155573/56745335-8b158a00-6750-11e9-8776-83fa675939c4.png - :target: https://notebooks.ai/demo/gh/Julian/jsonschema - :alt: Open Live Demo - - -Online demo Notebook will look similar to this: - - -.. image:: https://user-images.githubusercontent.com/1155573/56820861-5c1c1880-6823-11e9-802a-ce01c5ec574f.gif - :alt: Open Live Demo - :width: 480 px - - -Release Notes -------------- - -v3.1 brings support for ECMA 262 dialect regular expressions -throughout schemas, as recommended by the specification. Big -thanks to @Zac-HD for authoring support in a new `js-regex -`_ library. - - Running the Test Suite ---------------------- @@ -133,45 +109,38 @@ ---------- ``jsonschema``'s benchmarks make use of `pyperf -`_. - -Running them can be done via ``tox -e perf``, or by invoking the ``pyperf`` -commands externally (after ensuring that both it and ``jsonschema`` itself are -installed):: +`_. Running them can be done via:: - $ python -m pyperf jsonschema/benchmarks/test_suite.py --hist --output results.json - -To compare to a previous run, use:: - - $ python -m pyperf compare_to --table reference.json results.json - -See the ``pyperf`` documentation for more details. + $ tox -e perf Community --------- -There's a `mailing list `_ -for this implementation on Google Groups. +The JSON Schema specification has `a Slack +`_, with an `invite link on its home page +`_. Many folks knowledgeable on authoring +schemas can be found there. -Please join, and feel free to send questions there. +Otherwise, asking questions on Stack Overflow is another means of +getting help if you're stuck. -Contributing ------------- +About +----- I'm Julian Berman. -``jsonschema`` is on `GitHub `_. +``jsonschema`` is on `GitHub `_. Get in touch, via GitHub or otherwise, if you've got something to contribute, it'd be most welcome! -You can also generally find me on Freenode (nick: ``tos9``) in various +You can also generally find me on Libera (nick: ``Julian``) in various channels, including ``#python``. -If you feel overwhelmingly grateful, you can also woo me with beer money -via Google Pay with the email in my GitHub profile. +If you feel overwhelmingly grateful, you can also `sponsor me +`_. And for companies who appreciate ``jsonschema`` and its continued support and growth, ``jsonschema`` is also now supportable via `TideLift diff -Nru python-jsonschema-3.2.0/.readthedocs.yml python-jsonschema-4.6.0/.readthedocs.yml --- python-jsonschema-3.2.0/.readthedocs.yml 1970-01-01 00:00:00.000000000 +0000 +++ python-jsonschema-4.6.0/.readthedocs.yml 2022-06-01 20:26:26.000000000 +0000 @@ -0,0 +1,15 @@ +version: 2 + +sphinx: + builder: dirhtml + configuration: docs/conf.py + fail_on_warning: true + +formats: all + +python: + version: 3.8 + install: + - requirements: docs/requirements.txt + - method: pip + path: . diff -Nru python-jsonschema-3.2.0/setup.cfg python-jsonschema-4.6.0/setup.cfg --- python-jsonschema-3.2.0/setup.cfg 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/setup.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -[metadata] -name = jsonschema -url = https://github.com/Julian/jsonschema -project_urls = - Docs = https://python-jsonschema.readthedocs.io/en/latest/ -description = An implementation of JSON Schema validation for Python -long_description = file: README.rst -author = Julian Berman -author_email = Julian@GrayVines.com -classifiers = - Development Status :: 5 - Production/Stable - Intended Audience :: Developers - License :: OSI Approved :: MIT License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: Implementation :: CPython - Programming Language :: Python :: Implementation :: PyPy - -[options] -packages = find: -setup_requires = setuptools_scm -install_requires = - attrs>=17.4.0 - importlib_metadata;python_version<'3.8' - pyrsistent>=0.14.0 - setuptools - six>=1.11.0 - functools32;python_version<'3' - -[options.extras_require] -format = - idna - jsonpointer>1.13 - rfc3987 - strict-rfc3339 - webcolors -format_nongpl = - idna - jsonpointer>1.13 - webcolors - rfc3986-validator>0.1.0 - rfc3339-validator - -[options.entry_points] -console_scripts = - jsonschema = jsonschema.cli:main - -[options.package_data] -jsonschema = schemas/*.json - -[bdist_wheel] -universal = 1 - -[flake8] -builtins = unicode -exclude = - jsonschema/__init__.py - jsonschema/_reflect.py - -[pydocstyle] -match = (?!(test_|_|compat|cli)).*\.py # see PyCQA/pydocstyle#323 -add-select = - D410, # Trailing whitespace plz -add-ignore = - D107, # Hah, no - D200, # 1-line docstrings don't need to be on one line - D202, # One line is fine. - D412, # Trailing whitespace plz - D413, # No trailing whitespace plz diff -Nru python-jsonschema-3.2.0/setup.py python-jsonschema-4.6.0/setup.py --- python-jsonschema-3.2.0/setup.py 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/setup.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -from setuptools import setup -setup(use_scm_version=True) diff -Nru python-jsonschema-3.2.0/test-requirements.txt python-jsonschema-4.6.0/test-requirements.txt --- python-jsonschema-3.2.0/test-requirements.txt 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/test-requirements.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Twisted diff -Nru python-jsonschema-3.2.0/tox.ini python-jsonschema-4.6.0/tox.ini --- python-jsonschema-3.2.0/tox.ini 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/tox.ini 2022-06-01 20:26:26.000000000 +0000 @@ -1,60 +1,53 @@ [tox] envlist = - py{35,36,37,38,py,py3}-{build,tests,tests_nongpl}, - demo + py{37,38,39,310,311,py3}-{noextra,format,format_nongpl}-{build,tests}, readme safety secrets style + typing docs-{html,doctest,linkcheck,spelling,style} skipsdist = True [testenv] -changedir = - !build: {envtmpdir} +changedir = {envtmpdir} +passenv = CODECOV* CI setenv = JSON_SCHEMA_TEST_SUITE = {toxinidir}/json + + coverage,codecov: MAYBE_COVERAGE = coverage run -m + coverage,codecov: COVERAGE_RCFILE={toxinidir}/.coveragerc + coverage,codecov: COVERAGE_DEBUG_FILE={envtmpdir}/coverage-debug + coverage,codecov: COVERAGE_FILE={envtmpdir}/coverage-data whitelist_externals = - python2.7 mkdir - rm - sh - virtualenv commands = - perf,tests: {envbindir}/python -m pip install '{toxinidir}[format]' - tests_nongpl: {envbindir}/python -m pip install '{toxinidir}[format_nongpl]' + {envpython} -m pip install 'pip>=21.1.1' # Evade CVE-2021-28363 + + noextra: {envpython} -m pip install {toxinidir} + format,perf: {envpython} -m pip install '{toxinidir}[format]' + format_nongpl: {envpython} -m pip install '{toxinidir}[format_nongpl]' - tests,tests_nongpl: {envbindir}/trial {posargs:jsonschema} + # Ignore the deprecation warning until pypa/setuptools#3276 is released + tests,coverage,codecov: {envpython} -Werror -W"ignore:module 'sre_constants' is deprecated:DeprecationWarning" -m {env:MAYBE_COVERAGE:} twisted.trial {posargs:jsonschema} tests: {envpython} -m doctest {toxinidir}/README.rst + coverage: {envpython} -m coverage report --show-missing + coverage: {envpython} -m coverage html --directory={envtmpdir}/htmlcov + codecov: {envpython} -m coverage xml -o {envtmpdir}/coverage.xml + codecov: codecov --required --disable gcov --file {envtmpdir}/coverage.xml + perf: mkdir {envtmpdir}/benchmarks/ perf: {envpython} {toxinidir}/jsonschema/benchmarks/issue232.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/issue232.json perf: {envpython} {toxinidir}/jsonschema/benchmarks/json_schema_test_suite.py --inherit-environ JSON_SCHEMA_TEST_SUITE --output {envtmpdir}/benchmarks/json_schema_test_suite.json - # Check to make sure that releases build and install properly - build: virtualenv --quiet --python=python2.7 {envtmpdir}/venv - build: {envtmpdir}/venv/bin/pip install --quiet wheel - - build: {envtmpdir}/venv/bin/python {toxinidir}/setup.py --quiet bdist_wheel --dist-dir={envtmpdir}/wheel - build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/wheel/jsonschema*.whl' - - build: python2.7 {toxinidir}/setup.py --quiet sdist --dist-dir={envtmpdir}/sdist --format=gztar,zip - build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.tar.gz' - build: sh -c '{envbindir}/pip install --quiet --upgrade --force-reinstall {envtmpdir}/sdist/jsonschema*.zip' - - build: {envbindir}/python -m pep517.check {toxinidir} - - # FIXME: This has side effects! But it's not my fault... I can't - # figure out yet how to get setuptools to not create this directory - # here yet. But whatever, probably this will change to pep517.build - # soon anways. - build: rm -rf {toxinidir}/jsonschema.egg-info + build: {envpython} -m build {toxinidir} --outdir {envtmpdir}/dist deps = - build: pep517 + build: build perf: pyperf - tests,tests_nongpl,coverage,codecov: -r{toxinidir}/test-requirements.txt + tests,coverage,codecov: twisted coverage,codecov: coverage codecov: codecov @@ -63,91 +56,70 @@ deps = bandit commands = {envbindir}/bandit --recursive {toxinidir}/jsonschema -[testenv:demo] -deps = jupyter -commands = - {envbindir}/jupyter nbconvert --output-dir {envtmpdir} {toxinidir}/DEMO.ipynb - [testenv:readme] -changedir = {toxinidir} -deps = readme_renderer -commands = - {envbindir}/python setup.py check --restructuredtext --strict +deps = + build + docutils + twine +commands = + {envpython} -m build --outdir {envtmpdir}/dist {toxinidir} + {envpython} -m twine check {envtmpdir}/dist/* + {envbindir}/rst2html5.py --halt=warning {toxinidir}/CHANGELOG.rst /dev/null [testenv:safety] deps = safety commands = - {envbindir}/pip install '{toxinidir}[format]' - {envbindir}/safety check + {envpython} -m pip install 'pip>=21.1.1' # Evade CVE-2021-28363 + + # Remove once pypa/pip#7555 is closed. + {envpython} -m pip install --use-feature=in-tree-build '{toxinidir}[format]' + + {envpython} -m safety check [testenv:secrets] deps = detect-secrets commands = {envbindir}/detect-secrets scan {toxinidir} [testenv:style] -basepython = pypy3 deps = - ebb-lint>=0.19.1.0 -commands = - {envbindir}/flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs {toxinidir}/setup.py + flake8 + flake8-broken-line + flake8-bugbear + flake8-commas + flake8-quotes + flake8-tidy-imports +commands = + {envpython} -m flake8 {posargs} {toxinidir}/jsonschema {toxinidir}/docs + +[testenv:typing] +skip_install = true +deps = + mypy + pyrsistent + types-attrs + types-requests +commands = {envpython} -m mypy --config {toxinidir}/pyproject.toml {posargs} {toxinidir}/jsonschema -[testenv:coverage] -setenv = - {[testenv]setenv} - COVERAGE_DEBUG_FILE={envtmpdir}/coverage-debug - COVERAGE_FILE={envtmpdir}/coverage-data -commands = - {envbindir}/python -m pip install '{toxinidir}[format]' - {envbindir}/coverage run --rcfile={toxinidir}/.coveragerc {envbindir}/trial jsonschema - {envbindir}/coverage report --rcfile={toxinidir}/.coveragerc --show-missing - {envbindir}/coverage html --directory={envtmpdir}/htmlcov --rcfile={toxinidir}/.coveragerc {posargs} - -[testenv:docs-html] -basepython = pypy3 -commands = {envpython} -m sphinx -b html {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} +[testenv:docs-dirhtml] +commands = {envpython} -m sphinx -b dirhtml {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} deps = -r{toxinidir}/docs/requirements.txt - {toxinidir} [testenv:docs-doctest] -basepython = pypy3 commands = {envpython} -m sphinx -b doctest {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} -deps = - -r{toxinidir}/docs/requirements.txt - {toxinidir} +deps = {[testenv:docs-dirhtml]deps} [testenv:docs-linkcheck] -basepython = pypy3 commands = {envpython} -m sphinx -b linkcheck {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} -deps = - -r{toxinidir}/docs/requirements.txt - {toxinidir} +deps = {[testenv:docs-dirhtml]deps} [testenv:docs-spelling] -basepython = pypy3 -commands = {envpython} -m sphinx -b spelling {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -q -T -W} -deps = - -r{toxinidir}/docs/requirements.txt - {toxinidir} +commands = {envpython} -m sphinx -b spelling {toxinidir}/docs/ {envtmpdir}/build {posargs:-a -n -T -W} +deps = {[testenv:docs-dirhtml]deps} [testenv:docs-style] -basepython = pypy3 commands = doc8 {posargs} {toxinidir}/docs deps = doc8 pygments pygments-github-lexers - -[testenv:codecov] -passenv = CODECOV* CI TRAVIS TRAVIS_* -setenv = {[testenv:coverage]setenv} -commands = - {envbindir}/python -m pip install '{toxinidir}[format]' - {envbindir}/coverage run --rcfile={toxinidir}/.coveragerc {envbindir}/trial jsonschema - {envbindir}/coverage xml -o {envtmpdir}/coverage.xml - codecov --required --disable gcov --file {envtmpdir}/coverage.xml - -[travis] -python = - pypy: pypy, readme, safety, secrets - pypy3: pypy3, demo, docs, style diff -Nru python-jsonschema-3.2.0/.travis.yml python-jsonschema-4.6.0/.travis.yml --- python-jsonschema-3.2.0/.travis.yml 2019-11-18 12:36:14.000000000 +0000 +++ python-jsonschema-4.6.0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -sudo: false - -language: python - -dist: xenial - -python: - - 3.5 - - 3.6 - - 3.7 - - 3.8 - - pypy - - pypy3 - -install: - - pip install tox-travis - -script: - - tox - -after_success: - - tox -e codecov - -addons: - apt: - packages: - - libenchant-dev - -git: - depth: false