diff options
author | willson-chen <willson.chenwx@gmail.com> | 2020-08-29 16:03:31 +0800 |
---|---|---|
committer | willson-chen <willson.chenwx@gmail.com> | 2020-08-29 16:36:34 +0800 |
commit | 26aa142e78ff7d788f888745ef58f07275ac3bfc (patch) | |
tree | 5dcf8ee0cc860723fce9dbb360762a34abfac3c8 | |
parent | b936179ddc60cb88fed0a06f5bb9ebb13f4d0ae3 (diff) | |
download | jsonschema-26aa142e78ff7d788f888745ef58f07275ac3bfc.tar.gz |
support for cli specifying --base-uri local or remote and add test cases
-rw-r--r-- | jsonschema/cli.py | 37 | ||||
-rw-r--r-- | jsonschema/tests/test_cli.py | 129 |
2 files changed, 152 insertions, 14 deletions
diff --git a/jsonschema/cli.py b/jsonschema/cli.py index 2ae93c2..9314a56 100644 --- a/jsonschema/cli.py +++ b/jsonschema/cli.py @@ -10,6 +10,7 @@ import json import os import sys import traceback +import urllib import attr @@ -263,20 +264,30 @@ def run(arguments, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin): if arguments["base_uri"] is None: resolver = None - elif "http:" in arguments["base_uri"] or "https:" in arguments["base_uri"]\ - or "urn:" in arguments["base_uri"]: - resolver = RefResolver( - base_uri=arguments["base_uri"], - referrer=schema, - ) else: - file_prefix = "file:///{}/" if "nt" == os.name else "file://{}/" - resolver = RefResolver( - base_uri=file_prefix.format( - os.path.abspath(arguments["base_uri"]) - ), - referrer=schema, - ) + scheme = urllib.parse.urlsplit(arguments["base_uri"]).scheme + alphabet_list = [chr(ord('a') + i) for i in range(0, 26)] + local_path_flag = True \ + if scheme == '' or scheme in alphabet_list else False + + if local_path_flag: + file_prefix = "file:///{}/" if "nt" == os.name else "file://{}/" + abs_path_flag = os.path.isabs(arguments["base_uri"]) + + resolver = RefResolver( + base_uri=file_prefix.format(arguments["base_uri"]), + referrer=schema, + ) if abs_path_flag is True else RefResolver( + base_uri=file_prefix.format( + os.path.abspath(arguments["base_uri"]) + ), + referrer=schema, + ) + else: + resolver = RefResolver( + base_uri=arguments["base_uri"], + referrer=schema, + ) validator = arguments["validator"](schema, resolver=resolver) exit_code = 0 diff --git a/jsonschema/tests/test_cli.py b/jsonschema/tests/test_cli.py index 2bf0ac4..3b73dce 100644 --- a/jsonschema/tests/test_cli.py +++ b/jsonschema/tests/test_cli.py @@ -684,7 +684,7 @@ class TestCLI(TestCase): stderr="", ) - def test_successful_validation_with_specifying_base_uri(self): + def test_successful_validate_with_specifying_base_uri_relative_path(self): try: schema_file = tempfile.NamedTemporaryFile( mode='w+', @@ -710,6 +710,133 @@ class TestCLI(TestCase): stderr="", ) + def test_failure_validate_with_specifying_base_uri_relative_path(self): + try: + schema_file = tempfile.NamedTemporaryFile( + mode='w+', + prefix='schema', + suffix='.json', + dir='..', + delete=False + ) + self.addCleanup(os.remove, schema_file.name) + schema = """ + {"type": "object", "properties": {"KEY1": + {"$ref": %s%s#definitions/schemas"}}, + "definitions": {"schemas": {"type": "string"}}} + """ % ("\"", os.path.basename(schema_file.name)) + schema_file.write(schema) + finally: + schema_file.close() + + self.assertOutputs( + files=dict(some_schema=schema, some_instance='{"KEY1": 1}'), + argv=["-i", "some_instance", "--base-uri", "..", "some_schema"], + exit_code=1, + stdout="", + stderr="1: 1 is not of type 'string'\n", + ) + + def test_successful_validate_with_specifying_base_uri_absolute_path(self): + absolute_path = os.getcwd() + try: + schema_file = tempfile.NamedTemporaryFile( + mode='w+', + prefix='schema', + suffix='.json', + dir=absolute_path, + delete=False + ) + self.addCleanup(os.remove, schema_file.name) + schema = """ + {"type": "object", "properties": {"KEY1": + {"$ref": %s%s#definitions/schemas"}}, + "definitions": {"schemas": {"type": "string"}}} + """ % ("\"", os.path.basename(schema_file.name)) + schema_file.write(schema) + finally: + schema_file.close() + + self.assertOutputs( + files=dict(some_schema=schema, some_instance='{"KEY1": "1"}'), + argv=[ + "-i", "some_instance", + "--base-uri", absolute_path, + "some_schema", + ], + stdout="", + stderr="", + ) + + def test_failure_validate_with_specifying_base_uri_absolute_path(self): + absolute_path = os.getcwd() + try: + schema_file = tempfile.NamedTemporaryFile( + mode='w+', + prefix='schema', + suffix='.json', + dir=absolute_path, + delete=False + ) + self.addCleanup(os.remove, schema_file.name) + schema = """ + {"type": "object", "properties": {"KEY1": + {"$ref": %s%s#definitions/schemas"}}, + "definitions": {"schemas": {"type": "string"}}} + """ % ("\"", os.path.basename(schema_file.name)) + schema_file.write(schema) + finally: + schema_file.close() + + self.assertOutputs( + files=dict(some_schema=schema, some_instance='{"KEY1": 1}'), + argv=[ + "-i", "some_instance", + "--base-uri", absolute_path, + "some_schema", + ], + exit_code=1, + stdout="", + stderr="1: 1 is not of type 'string'\n", + ) + + def test_successful_validate_with_specifying_base_uri_remote_path(self): + schema = """ + {"type": "object", "properties": { + "KEY1":{"$ref": "organization.json"}}} + """ + self.assertOutputs( + files=dict(some_schema=schema, + some_instance='{"KEY1": {"name": "remote"}}' + ), + argv=[ + "-i", "some_instance", + "--base-uri", "https://project-open-data.cio.gov/v1.1/schema/", + "some_schema", + ], + stdout="", + stderr="", + ) + + def test_failure_validate_with_specifying_base_uri_remote_path(self): + schema = """ + {"type": "object", "properties": { + "KEY1":{"$ref": "organization.json"}}} + """ + self.assertOutputs( + files=dict(some_schema=schema, + some_instance='{"KEY1": {"fail": "remote"}}' + ), + argv=[ + "-i", "some_instance", + "--base-uri", "https://project-open-data.cio.gov/v1.1/schema/", + "some_schema", + ], + exit_code=1, + stdout="", + stderr="{'fail': 'remote'}: 'name' is a required property\n", + ) + 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 |