123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 |
- from contextlib import redirect_stderr, redirect_stdout
- from importlib import metadata
- 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
- import warnings
- from jsonschema import Draft4Validator, Draft202012Validator
- from jsonschema.exceptions import (
- SchemaError,
- ValidationError,
- _RefResolutionError,
- )
- from jsonschema.validators import _LATEST_VERSION, validate
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- from jsonschema import cli
- def fake_validator(*errors):
- errors = list(reversed(errors))
- class FakeValidator:
- def __init__(self, *args, **kwargs):
- pass
- def iter_errors(self, instance):
- if errors:
- return errors.pop()
- 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=None, stdin=StringIO(), exit_code=0, **override,
- ):
- arguments = cli.parse_args(argv)
- arguments.update(override)
- self.assertFalse(hasattr(cli, "open"))
- cli.open = fake_open(files or {})
- 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(
- f"""
- Expected an exit code of {exit_code} != {actual_exit_code}.
- stdout: {stdout.getvalue()}
- stderr: {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=f"""\
- Failed to parse 'some_instance': {_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=f"""\
- Failed to parse <stdin>: {_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(
- "(<stdin>)===\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=f"""\
- Failed to parse 'some_schema': {_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=f"""\
- Failed to parse 'some_schema': {_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]===(<stdin>)===\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)
- ref_schema_file.close()
- 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)
- ref_schema_file.close()
- 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_explicit_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()
- def test_find_validator_by_fully_qualified_object_name(self):
- arguments = cli.parse_args(
- [
- "--validator",
- "jsonschema.tests.test_cli.TestParser.FakeValidator",
- "--instance", "mem://some/instance",
- "mem://some/schema",
- ],
- )
- self.assertIs(arguments["validator"], self.FakeValidator)
- def test_find_validator_in_jsonschema(self):
- arguments = cli.parse_args(
- [
- "--validator", "Draft4Validator",
- "--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): # noqa: SIM117
- 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)
- 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)
- 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(
- [sys.executable, "-W", "ignore", "-m", "jsonschema", "--version"],
- stderr=subprocess.STDOUT,
- )
- version = version.decode("utf-8").strip()
- 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)
|