Skip to content

Commit 26aa142

Browse files
committed
support for cli specifying --base-uri local or remote and add test cases
1 parent b936179 commit 26aa142

File tree

2 files changed

+152
-14
lines changed

2 files changed

+152
-14
lines changed

jsonschema/cli.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import os
1111
import sys
1212
import traceback
13+
import urllib
1314

1415
import attr
1516

@@ -263,20 +264,30 @@ def load(_):
263264

264265
if arguments["base_uri"] is None:
265266
resolver = None
266-
elif "http:" in arguments["base_uri"] or "https:" in arguments["base_uri"]\
267-
or "urn:" in arguments["base_uri"]:
268-
resolver = RefResolver(
269-
base_uri=arguments["base_uri"],
270-
referrer=schema,
271-
)
272267
else:
273-
file_prefix = "file:///{}/" if "nt" == os.name else "file://{}/"
274-
resolver = RefResolver(
275-
base_uri=file_prefix.format(
276-
os.path.abspath(arguments["base_uri"])
277-
),
278-
referrer=schema,
279-
)
268+
scheme = urllib.parse.urlsplit(arguments["base_uri"]).scheme
269+
alphabet_list = [chr(ord('a') + i) for i in range(0, 26)]
270+
local_path_flag = True \
271+
if scheme == '' or scheme in alphabet_list else False
272+
273+
if local_path_flag:
274+
file_prefix = "file:///{}/" if "nt" == os.name else "file://{}/"
275+
abs_path_flag = os.path.isabs(arguments["base_uri"])
276+
277+
resolver = RefResolver(
278+
base_uri=file_prefix.format(arguments["base_uri"]),
279+
referrer=schema,
280+
) if abs_path_flag is True else RefResolver(
281+
base_uri=file_prefix.format(
282+
os.path.abspath(arguments["base_uri"])
283+
),
284+
referrer=schema,
285+
)
286+
else:
287+
resolver = RefResolver(
288+
base_uri=arguments["base_uri"],
289+
referrer=schema,
290+
)
280291

281292
validator = arguments["validator"](schema, resolver=resolver)
282293
exit_code = 0

jsonschema/tests/test_cli.py

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ def test_successful_validation_of_just_the_schema_pretty_output(self):
684684
stderr="",
685685
)
686686

687-
def test_successful_validation_with_specifying_base_uri(self):
687+
def test_successful_validate_with_specifying_base_uri_relative_path(self):
688688
try:
689689
schema_file = tempfile.NamedTemporaryFile(
690690
mode='w+',
@@ -710,6 +710,133 @@ def test_successful_validation_with_specifying_base_uri(self):
710710
stderr="",
711711
)
712712

713+
def test_failure_validate_with_specifying_base_uri_relative_path(self):
714+
try:
715+
schema_file = tempfile.NamedTemporaryFile(
716+
mode='w+',
717+
prefix='schema',
718+
suffix='.json',
719+
dir='..',
720+
delete=False
721+
)
722+
self.addCleanup(os.remove, schema_file.name)
723+
schema = """
724+
{"type": "object", "properties": {"KEY1":
725+
{"$ref": %s%s#definitions/schemas"}},
726+
"definitions": {"schemas": {"type": "string"}}}
727+
""" % ("\"", os.path.basename(schema_file.name))
728+
schema_file.write(schema)
729+
finally:
730+
schema_file.close()
731+
732+
self.assertOutputs(
733+
files=dict(some_schema=schema, some_instance='{"KEY1": 1}'),
734+
argv=["-i", "some_instance", "--base-uri", "..", "some_schema"],
735+
exit_code=1,
736+
stdout="",
737+
stderr="1: 1 is not of type 'string'\n",
738+
)
739+
740+
def test_successful_validate_with_specifying_base_uri_absolute_path(self):
741+
absolute_path = os.getcwd()
742+
try:
743+
schema_file = tempfile.NamedTemporaryFile(
744+
mode='w+',
745+
prefix='schema',
746+
suffix='.json',
747+
dir=absolute_path,
748+
delete=False
749+
)
750+
self.addCleanup(os.remove, schema_file.name)
751+
schema = """
752+
{"type": "object", "properties": {"KEY1":
753+
{"$ref": %s%s#definitions/schemas"}},
754+
"definitions": {"schemas": {"type": "string"}}}
755+
""" % ("\"", os.path.basename(schema_file.name))
756+
schema_file.write(schema)
757+
finally:
758+
schema_file.close()
759+
760+
self.assertOutputs(
761+
files=dict(some_schema=schema, some_instance='{"KEY1": "1"}'),
762+
argv=[
763+
"-i", "some_instance",
764+
"--base-uri", absolute_path,
765+
"some_schema",
766+
],
767+
stdout="",
768+
stderr="",
769+
)
770+
771+
def test_failure_validate_with_specifying_base_uri_absolute_path(self):
772+
absolute_path = os.getcwd()
773+
try:
774+
schema_file = tempfile.NamedTemporaryFile(
775+
mode='w+',
776+
prefix='schema',
777+
suffix='.json',
778+
dir=absolute_path,
779+
delete=False
780+
)
781+
self.addCleanup(os.remove, schema_file.name)
782+
schema = """
783+
{"type": "object", "properties": {"KEY1":
784+
{"$ref": %s%s#definitions/schemas"}},
785+
"definitions": {"schemas": {"type": "string"}}}
786+
""" % ("\"", os.path.basename(schema_file.name))
787+
schema_file.write(schema)
788+
finally:
789+
schema_file.close()
790+
791+
self.assertOutputs(
792+
files=dict(some_schema=schema, some_instance='{"KEY1": 1}'),
793+
argv=[
794+
"-i", "some_instance",
795+
"--base-uri", absolute_path,
796+
"some_schema",
797+
],
798+
exit_code=1,
799+
stdout="",
800+
stderr="1: 1 is not of type 'string'\n",
801+
)
802+
803+
def test_successful_validate_with_specifying_base_uri_remote_path(self):
804+
schema = """
805+
{"type": "object", "properties": {
806+
"KEY1":{"$ref": "organization.json"}}}
807+
"""
808+
self.assertOutputs(
809+
files=dict(some_schema=schema,
810+
some_instance='{"KEY1": {"name": "remote"}}'
811+
),
812+
argv=[
813+
"-i", "some_instance",
814+
"--base-uri", "https://project-open-data.cio.gov/v1.1/schema/",
815+
"some_schema",
816+
],
817+
stdout="",
818+
stderr="",
819+
)
820+
821+
def test_failure_validate_with_specifying_base_uri_remote_path(self):
822+
schema = """
823+
{"type": "object", "properties": {
824+
"KEY1":{"$ref": "organization.json"}}}
825+
"""
826+
self.assertOutputs(
827+
files=dict(some_schema=schema,
828+
some_instance='{"KEY1": {"fail": "remote"}}'
829+
),
830+
argv=[
831+
"-i", "some_instance",
832+
"--base-uri", "https://project-open-data.cio.gov/v1.1/schema/",
833+
"some_schema",
834+
],
835+
exit_code=1,
836+
stdout="",
837+
stderr="{'fail': 'remote'}: 'name' is a required property\n",
838+
)
839+
713840
def test_it_validates_using_the_latest_validator_when_unspecified(self):
714841
# There isn't a better way now I can think of to ensure that the
715842
# latest version was used, given that the call to validator_for

0 commit comments

Comments
 (0)