diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 93111ca..328fe2e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,39 +15,9 @@ repos: - id: check-yaml - id: debug-statements - - repo: https://github.com/psf/black - rev: 26.1.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.0 hooks: - - id: black - args: [--line-length=88, --target-version=py35] - exclude: > - (?x)( - # black defaults - \.eggs - | \.git\ - | \.hg - | \.mypy_cache - | \.nox - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - - # sphinxcontrib-openapi - | sphinxcontrib/openapi/__init__.py - | sphinxcontrib/openapi/__main__.py - | sphinxcontrib/openapi/openapi20.py - | sphinxcontrib/openapi/openapi30.py - | sphinxcontrib/openapi/directive.py - | sphinxcontrib/openapi/utils.py - | tests/test_openapi.py - | tests/conftest.py - | tests/test_spec_examples.py - ) - - - repo: https://github.com/pycqa/flake8 - rev: 7.3.0 - hooks: - - id: flake8 + - id: ruff-check + args: ['--fix', '--unsafe-fixes'] + - id: ruff-format diff --git a/pyproject.toml b/pyproject.toml index a4f8b24..7c13702 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,3 +51,10 @@ include-package-data = true include = ["sphinxcontrib.*"] [tool.setuptools_scm] + +[tool.ruff.format] +docstring-code-format = true + +[tool.ruff.lint] +select = ["E4", "E5", "E7", "E9", "F", "RUF", "UP", "W"] +ignore = ["RUF012"] diff --git a/sphinxcontrib/openapi/__init__.py b/sphinxcontrib/openapi/__init__.py index d5e0448..9ebfd40 100644 --- a/sphinxcontrib/openapi/__init__.py +++ b/sphinxcontrib/openapi/__init__.py @@ -1,12 +1,12 @@ """ - sphinxcontrib.openapi - --------------------- +sphinxcontrib.openapi +--------------------- - The OpenAPI spec renderer for Sphinx. It's a new way to document your - RESTful API. Based on ``sphinxcontrib-httpdomain``. +The OpenAPI spec renderer for Sphinx. It's a new way to document your +RESTful API. Based on ``sphinxcontrib-httpdomain``. - :copyright: (c) 2016, Ihor Kalnytskyi. - :license: BSD, see LICENSE for details. +:copyright: (c) 2016, Ihor Kalnytskyi. +:license: BSD, see LICENSE for details. """ from importlib.metadata import distribution, PackageNotFoundError @@ -34,14 +34,14 @@ def _register_rendering_directives(app, conf): for renderer_name, renderer_cls in renderers_map.items(): app.add_directive( - "openapi:%s" % renderer_name, + f"openapi:{renderer_name}", directive.create_directive_from_renderer(renderer_cls), ) if conf.openapi_default_renderer not in renderers_map: raise ValueError( "invalid 'openapi_default_renderer' value: " - "no such renderer: '%s'" % conf.openapi_default_renderer + f"no such renderer: '{conf.openapi_default_renderer}'" ) app.add_directive( @@ -59,22 +59,22 @@ def setup(app): from sphinxcontrib import httpdomain for idx, fieldtype in enumerate(httpdomain.HTTPResource.doc_field_types): - if fieldtype.name == 'requestheader': + if fieldtype.name == "requestheader": httpdomain.HTTPResource.doc_field_types[idx] = httpdomain.TypedField( fieldtype.name, label=fieldtype.label, names=fieldtype.names, - typerolename='header', - typenames=('reqheadertype', ), + typerolename="header", + typenames=("reqheadertype",), ) - if fieldtype.name == 'responseheader': + if fieldtype.name == "responseheader": httpdomain.HTTPResource.doc_field_types[idx] = httpdomain.TypedField( fieldtype.name, label=fieldtype.label, names=fieldtype.names, - typerolename='header', - typenames=('resheadertype', ), + typerolename="header", + typenames=("resheadertype",), ) app.setup_extension("sphinxcontrib.httpdomain") diff --git a/sphinxcontrib/openapi/__main__.py b/sphinxcontrib/openapi/__main__.py index e7530a5..044cb90 100644 --- a/sphinxcontrib/openapi/__main__.py +++ b/sphinxcontrib/openapi/__main__.py @@ -6,67 +6,68 @@ def main(): parser = argparse.ArgumentParser( - prog='oas2rst', - description='Export OpenAPI Specification files to reStructuredText \ - files') + prog="oas2rst", + description="Export OpenAPI Specification files to reStructuredText \ + files", + ) parser.add_argument( - "-l", "--level", - action='store', + "-l", + "--level", + action="store", default=logging.INFO, - dest='level', - help="Logging level") + dest="level", + help="Logging level", + ) parser.add_argument( - "-e", "--encoding", - action='store', + "-e", + "--encoding", + action="store", default="UTF-8", - dest='encoding', - help="Source file encoding") + dest="encoding", + help="Source file encoding", + ) parser.add_argument( - "-p", "--paths", - action='append', - dest='paths', - help="Endpoints to be rendered") + "-p", "--paths", action="append", dest="paths", help="Endpoints to be rendered" + ) parser.add_argument( - "-x", "--examples", - action='store_true', - dest='examples', - help="Include examples") + "-x", + "--examples", + action="store_true", + dest="examples", + help="Include examples", + ) parser.add_argument( - "-g", "--group", - action='store_true', - dest='group', - help="Group paths by tag") + "-g", "--group", action="store_true", dest="group", help="Group paths by tag" + ) + parser.add_argument("-i", "--input", dest="input", required=True, help="Input file") parser.add_argument( - "-i", "--input", - dest='input', + "-o", + "--output", + type=argparse.FileType("w"), required=True, - help="Input file") - parser.add_argument( - "-o", "--output", - type=argparse.FileType('w'), - required=True, - dest='output', - help="Output file") + dest="output", + help="Output file", + ) options = parser.parse_args() logging.getLogger().setLevel(options.level) openapi_options = {} if options.paths: - openapi_options['paths'] = options.paths + openapi_options["paths"] = options.paths if options.examples: - openapi_options['examples'] = True + openapi_options["examples"] = True if options.group: - openapi_options['group'] = True + openapi_options["group"] = True - openapi_options.setdefault('uri', 'file://%s' % options.input) + openapi_options.setdefault("uri", f"file://{options.input}") spec = directive._get_spec(options.input, options.encoding) renderer = renderers.HttpdomainOldRenderer(None, openapi_options) for line in renderer.render_restructuredtext_markup(spec): - options.output.write(line+'\n') + options.output.write(line + "\n") logging.debug(line) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/sphinxcontrib/openapi/directive.py b/sphinxcontrib/openapi/directive.py index d42785a..2a6da89 100644 --- a/sphinxcontrib/openapi/directive.py +++ b/sphinxcontrib/openapi/directive.py @@ -1,11 +1,11 @@ """ - sphinxcontrib.openapi.directive - ------------------------------- +sphinxcontrib.openapi.directive +------------------------------- - The main directive for the extension. +The main directive for the extension. - :copyright: (c) 2016, Ihor Kalnytskyi. - :license: BSD, see LICENSE for details. +:copyright: (c) 2016, Ihor Kalnytskyi. +:license: BSD, see LICENSE for details. """ import functools @@ -17,9 +17,9 @@ # Locally cache spec to speedup processing of same spec file in multiple # openapi directives -@functools.lru_cache() +@functools.lru_cache def _get_spec(abspath, encoding): - with open(abspath, 'rt', encoding=encoding) as stream: + with open(abspath, encoding=encoding) as stream: return yaml.safe_load(stream) @@ -27,13 +27,13 @@ def create_directive_from_renderer(renderer_cls): """Create rendering directive from a renderer class.""" class _RenderingDirective(SphinxDirective): - required_arguments = 1 # path to openapi spec - final_argument_whitespace = True # path may contain whitespaces + required_arguments = 1 # path to openapi spec + final_argument_whitespace = True # path may contain whitespaces option_spec = dict( { - 'encoding': directives.encoding, # useful for non-ascii cases :) + "encoding": directives.encoding, # useful for non-ascii cases :) }, - **renderer_cls.option_spec + **renderer_cls.option_spec, ) def run(self): @@ -42,7 +42,7 @@ def run(self): # URI parameter is crucial for resolving relative references. So we # need to set this option properly as it's used later down the # stack. - self.options.setdefault('uri', 'file://%s' % abspath) + self.options.setdefault("uri", f"file://{abspath}") # Add a given OpenAPI spec as a dependency of the referring # reStructuredText document, so the document is rebuilt each time @@ -51,7 +51,7 @@ def run(self): # Read the spec using encoding passed to the directive or fallback to # the one specified in Sphinx's config. - encoding = self.options.get('encoding', self.config.source_encoding) + encoding = self.options.get("encoding", self.config.source_encoding) spec = _get_spec(abspath, encoding) return renderer_cls(self.state, self.options).render(spec) diff --git a/sphinxcontrib/openapi/openapi20.py b/sphinxcontrib/openapi/openapi20.py index 9833b76..b9d5b16 100644 --- a/sphinxcontrib/openapi/openapi20.py +++ b/sphinxcontrib/openapi/openapi20.py @@ -1,15 +1,14 @@ """ - sphinxcontrib.openapi.openapi20 - ------------------------------- +sphinxcontrib.openapi.openapi20 +------------------------------- - The OpenAPI 2.0 (f.k.a. Swagger) spec renderer. Based on - ``sphinxcontrib-httpdomain``. +The OpenAPI 2.0 (f.k.a. Swagger) spec renderer. Based on +``sphinxcontrib-httpdomain``. - :copyright: (c) 2016, Ihor Kalnytskyi. - :license: BSD, see LICENSE for details. +:copyright: (c) 2016, Ihor Kalnytskyi. +:license: BSD, see LICENSE for details. """ -import collections import itertools import re @@ -17,83 +16,82 @@ def _httpresource(endpoint, method, properties, convert): - parameters = properties.get('parameters', []) - responses = properties['responses'] - indent = ' ' + parameters = properties.get("parameters", []) + responses = properties["responses"] + indent = " " - yield '.. http:{0}:: {1}'.format(method, endpoint) - yield ' :synopsis: {0}'.format(properties.get('summary', 'null')) - yield '' + yield f".. http:{method}:: {endpoint}" + yield " :synopsis: {}".format(properties.get("summary", "null")) + yield "" - if 'summary' in properties: - for line in properties['summary'].splitlines(): - yield '{indent}**{line}**'.format(**locals()) - yield '' + if "summary" in properties: + for line in properties["summary"].splitlines(): + yield "{indent}**{line}**".format(**locals()) + yield "" - if 'description' in properties: - for line in convert(properties['description']).splitlines(): - yield '{indent}{line}'.format(**locals()) - yield '' + if "description" in properties: + for line in convert(properties["description"]).splitlines(): + yield "{indent}{line}".format(**locals()) + yield "" - for param in filter(lambda p: p['in'] == 'path', parameters): - yield indent + ':param {type} {name}:'.format(**param) - for line in convert(param.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + for param in filter(lambda p: p["in"] == "path", parameters): + yield indent + ":param {type} {name}:".format(**param) + for line in convert(param.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) # print request's query params - for param in filter(lambda p: p['in'] == 'query', parameters): - yield indent + ':query {type} {name}:'.format(**param) - for line in convert(param.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + for param in filter(lambda p: p["in"] == "query", parameters): + yield indent + ":query {type} {name}:".format(**param) + for line in convert(param.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) # print the json body params - for param in filter(lambda p: p['in'] == 'body', parameters): - if 'schema' in param: - yield '' - for line in convert_json_schema(param['schema']): - yield '{indent}{line}'.format(**locals()) - yield '' + for param in filter(lambda p: p["in"] == "body", parameters): + if "schema" in param: + yield "" + for line in convert_json_schema(param["schema"]): + yield "{indent}{line}".format(**locals()) + yield "" # print response status codes for status, response in sorted(responses.items()): - yield '{indent}:status {status}:'.format(**locals()) - for line in convert(response.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + yield "{indent}:status {status}:".format(**locals()) + for line in convert(response.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) # print request header params - for param in filter(lambda p: p['in'] == 'header', parameters): - yield indent + ':reqheader {name}:'.format(**param) - for line in convert(param.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + for param in filter(lambda p: p["in"] == "header", parameters): + yield indent + ":reqheader {name}:".format(**param) + for line in convert(param.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) # print response headers for status, response in responses.items(): - for headername, header in response.get('headers', {}).items(): - yield indent + ':resheader {name}:'.format(name=headername) - for line in convert(header.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + for headername, header in response.get("headers", {}).items(): + yield indent + f":resheader {headername}:" + for line in convert(header.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) for status, response in responses.items(): if not is_2xx_response(status): continue - if 'schema' in response: - yield '' - for line in convert_json_schema( - response['schema'], directive=':>json'): - yield '{indent}{line}'.format(**locals()) - yield '' + if "schema" in response: + yield "" + for line in convert_json_schema(response["schema"], directive=":>json"): + yield "{indent}{line}".format(**locals()) + yield "" - yield '' + yield "" -def convert_json_schema(schema, directive=': + ("integer", None): 1, # integer + ("number", None): 1.0, # } _READONLY_PROPERTY = object() # sentinel for values not included in requests @@ -72,8 +70,11 @@ def _dict_merge(dct, merge_dct): merge_dct: dct merged into dct """ for k in merge_dct.keys(): - if (k in dct and isinstance(dct[k], dict) - and isinstance(merge_dct[k], collections.abc.Mapping)): + if ( + k in dct + and isinstance(dct[k], dict) + and isinstance(merge_dct[k], collections.abc.Mapping) + ): _dict_merge(dct[k], merge_dct[k]) else: dct[k] = merge_dct[k] @@ -84,15 +85,15 @@ def _parse_schema(schema, method): Convert a Schema Object to a Python object. Args: - schema: An ``OrderedDict`` representing the schema object. + schema: A dict representing the schema object. """ - if method and schema.get('readOnly', False): + if method and schema.get("readOnly", False): return _READONLY_PROPERTY # allOf: Must be valid against all of the subschemas - if 'allOf' in schema: - schema_ = copy.deepcopy(schema['allOf'][0]) - for x in schema['allOf'][1:]: + if "allOf" in schema: + schema_ = copy.deepcopy(schema["allOf"][0]) + for x in schema["allOf"][1:]: _dict_merge(schema_, x) return _parse_schema(schema_, method) @@ -101,53 +102,50 @@ def _parse_schema(schema, method): # TODO(stephenfin): Handle anyOf # oneOf: Must be valid against exactly one of the subschemas - if 'oneOf' in schema: + if "oneOf" in schema: # we only show the first one since we can't show everything - return _parse_schema(schema['oneOf'][0], method) + return _parse_schema(schema["oneOf"][0], method) - if 'enum' in schema: + if "enum" in schema: # we only show the first one since we can't show everything - return schema['enum'][0] + return schema["enum"][0] - schema_type = schema.get('type', 'object') + schema_type = schema.get("type", "object") - if schema_type == 'array': + if schema_type == "array": # special case oneOf and anyOf so that we can show examples for all # possible combinations - if 'oneOf' in schema['items']: - return [ - _parse_schema(x, method) for x in schema['items']['oneOf'] - ] - - if 'anyOf' in schema['items']: - return [ - _parse_schema(x, method) for x in schema['items']['anyOf'] - ] - - return [_parse_schema(schema['items'], method)] - - if schema_type == 'object': - if method and 'properties' in schema and \ - all(v.get('readOnly', False) - for v in schema['properties'].values()): + if "oneOf" in schema["items"]: + return [_parse_schema(x, method) for x in schema["items"]["oneOf"]] + + if "anyOf" in schema["items"]: + return [_parse_schema(x, method) for x in schema["items"]["anyOf"]] + + return [_parse_schema(schema["items"], method)] + + if schema_type == "object": + if ( + method + and "properties" in schema + and all(v.get("readOnly", False) for v in schema["properties"].values()) + ): return _READONLY_PROPERTY - results = [] - for name, prop in schema.get('properties', {}).items(): + results = {} + for name, prop in schema.get("properties", {}).items(): result = _parse_schema(prop, method) if result != _READONLY_PROPERTY: - results.append((name, result)) + results[name] = result - return collections.OrderedDict(results) + return results - if (schema_type, schema.get('format')) in _TYPE_MAPPING: - return _TYPE_MAPPING[(schema_type, schema.get('format'))] + if (schema_type, schema.get("format")) in _TYPE_MAPPING: + return _TYPE_MAPPING[(schema_type, schema.get("format"))] return _TYPE_MAPPING[(schema_type, None)] # unrecognized format -def _example(media_type_objects, method=None, endpoint=None, status=None, - nb_indent=0): +def _example(media_type_objects, method=None, endpoint=None, status=None, nb_indent=0): """ Format examples in `Media Type Object` openapi v3 to HTTP request or HTTP response example. @@ -161,7 +159,7 @@ def _example(media_type_objects, method=None, endpoint=None, status=None, endpoint: The HTTP route to use in example. status: The HTTP status to use in example. """ - indent = ' ' + indent = " " extra_indent = indent * nb_indent if method is not None: @@ -172,218 +170,220 @@ def _example(media_type_objects, method=None, endpoint=None, status=None, # in the case, just fallback to '-' status_text = http_status_codes[int(status)] except (ValueError, KeyError): - status_text = '-' + status_text = "-" # Provide request samples for GET requests - if method == 'GET': - media_type_objects[''] = { - 'examples': {'Example request': {'value': ''}}} + if method == "GET": + media_type_objects[""] = {"examples": {"Example request": {"value": ""}}} for content_type, content in media_type_objects.items(): - examples = content.get('examples') - example = content.get('example') + examples = content.get("examples") + example = content.get("example") # Try to get the example from the schema - if example is None and 'schema' in content: - example = content['schema'].get('example') + if example is None and "schema" in content: + example = content["schema"].get("example") if examples is None: examples = {} if not example: - if re.match(r"application/[a-zA-Z\+]*json", content_type) is \ - None: - LOG.info('skipping non-JSON example generation.') + if re.match(r"application/[a-zA-Z\+]*json", content_type) is None: + LOG.info("skipping non-JSON example generation.") continue - example = _parse_schema(content['schema'], method=method) + example = _parse_schema(content["schema"], method=method) if method is None: - examples['Example response'] = { - 'value': example, + examples["Example response"] = { + "value": example, } else: - examples['Example request'] = { - 'value': example, + examples["Example request"] = { + "value": example, } for example in examples.values(): # According to OpenAPI v3 specs, string examples should be left unchanged - if not isinstance(example['value'], str): - example['value'] = json.dumps( - example['value'], indent=4, separators=(',', ': ')) + if not isinstance(example["value"], str): + example["value"] = json.dumps( + example["value"], indent=4, separators=(",", ": ") + ) for example_name, example in examples.items(): - if 'summary' in example: - example_title = '{example_name} - {example[summary]}'.format( - **locals()) + if "summary" in example: + example_title = "{example_name} - {example[summary]}".format(**locals()) else: example_title = example_name - yield '' - yield '{extra_indent}**{example_title}:**'.format(**locals()) - yield '' - yield '{extra_indent}.. sourcecode:: http'.format(**locals()) - yield '' + yield "" + yield "{extra_indent}**{example_title}:**".format(**locals()) + yield "" + yield "{extra_indent}.. sourcecode:: http".format(**locals()) + yield "" # Print http request example if method: - yield '{extra_indent}{indent}{method} {endpoint} HTTP/1.1' \ - .format(**locals()) - yield '{extra_indent}{indent}Host: example.com' \ - .format(**locals()) + yield "{extra_indent}{indent}{method} {endpoint} HTTP/1.1".format( + **locals() + ) + yield "{extra_indent}{indent}Host: example.com".format(**locals()) if content_type: - yield '{extra_indent}{indent}Content-Type: {content_type}'\ - .format(**locals()) + yield "{extra_indent}{indent}Content-Type: {content_type}".format( + **locals() + ) # Print http response example else: - yield '{extra_indent}{indent}HTTP/1.1 {status} {status_text}' \ - .format(**locals()) - yield '{extra_indent}{indent}Content-Type: {content_type}' \ - .format(**locals()) + yield "{extra_indent}{indent}HTTP/1.1 {status} {status_text}".format( + **locals() + ) + yield "{extra_indent}{indent}Content-Type: {content_type}".format( + **locals() + ) - yield '' - for example_line in example['value'].splitlines(): - yield '{extra_indent}{indent}{example_line}'.format(**locals()) - if example['value'].splitlines(): - yield '' + yield "" + for example_line in example["value"].splitlines(): + yield "{extra_indent}{indent}{example_line}".format(**locals()) + if example["value"].splitlines(): + yield "" -def _httpresource(endpoint, method, properties, convert, render_examples, - render_request): +def _httpresource( + endpoint, method, properties, convert, render_examples, render_request +): # https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#operation-object - parameters = properties.get('parameters', []) - responses = properties['responses'] + parameters = properties.get("parameters", []) + responses = properties["responses"] query_param_examples = [] - indent = ' ' + indent = " " - yield '.. http:{0}:: {1}'.format(method, endpoint) - yield ' :synopsis: {0}'.format(properties.get('summary', 'null')) - yield '' + yield f".. http:{method}:: {endpoint}" + yield " :synopsis: {}".format(properties.get("summary", "null")) + yield "" - if 'summary' in properties: - for line in properties['summary'].splitlines(): - yield '{indent}**{line}**'.format(**locals()) - yield '' + if "summary" in properties: + for line in properties["summary"].splitlines(): + yield "{indent}**{line}**".format(**locals()) + yield "" - if 'description' in properties: - for line in convert(properties.get('description', '')).splitlines(): - yield '{indent}{line}'.format(**locals()) - yield '' + if "description" in properties: + for line in convert(properties.get("description", "")).splitlines(): + yield "{indent}{line}".format(**locals()) + yield "" # print request's path params - for param in filter(lambda p: p['in'] == 'path', parameters): - yield indent + ':param {type} {name}:'.format( - type=param['schema']['type'], - name=param['name']) + for param in filter(lambda p: p["in"] == "path", parameters): + yield indent + ":param {type} {name}:".format( + type=param["schema"]["type"], name=param["name"] + ) - for line in convert(param.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + for line in convert(param.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) # print request's query params - for param in filter(lambda p: p['in'] == 'query', parameters): - yield indent + ':query {type} {name}:'.format( - type=param['schema']['type'], - name=param['name']) - for line in convert(param.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) - if param.get('required', False): - yield '{indent}{indent}(Required)'.format(**locals()) - example = _parse_schema(param['schema'], method) - example = param.get('example', example) - if param.get('explode', False) and isinstance(example, list): + for param in filter(lambda p: p["in"] == "query", parameters): + yield indent + ":query {type} {name}:".format( + type=param["schema"]["type"], name=param["name"] + ) + for line in convert(param.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) + if param.get("required", False): + yield "{indent}{indent}(Required)".format(**locals()) + example = _parse_schema(param["schema"], method) + example = param.get("example", example) + if param.get("explode", False) and isinstance(example, list): for v in example: - query_param_examples.append((param['name'], v)) - elif param.get('explode', False) and isinstance(example, dict): + query_param_examples.append((param["name"], v)) + elif param.get("explode", False) and isinstance(example, dict): for k, v in example.items(): query_param_examples.append((k, v)) else: - query_param_examples.append((param['name'], example)) + query_param_examples.append((param["name"], example)) # print request content if render_request: - request_content = properties.get('requestBody', {}).get('content', {}) - if request_content and 'application/json' in request_content: - schema = request_content['application/json']['schema'] - req_properties = json.dumps(schema['properties'], indent=2, - separators=(',', ':')) - yield '{indent}**Request body:**'.format(**locals()) - yield '' - yield '{indent}.. sourcecode:: json'.format(**locals()) - yield '' + request_content = properties.get("requestBody", {}).get("content", {}) + if request_content and "application/json" in request_content: + schema = request_content["application/json"]["schema"] + req_properties = json.dumps( + schema["properties"], indent=2, separators=(",", ":") + ) + yield "{indent}**Request body:**".format(**locals()) + yield "" + yield "{indent}.. sourcecode:: json".format(**locals()) + yield "" for line in req_properties.splitlines(): # yield indent + line - yield '{indent}{indent}{line}'.format(**locals()) + yield "{indent}{indent}{line}".format(**locals()) # yield '' # print request example if render_examples: endpoint_examples = endpoint if query_param_examples: - endpoint_examples = endpoint + "?" + \ - parse.urlencode(query_param_examples) + endpoint_examples = endpoint + "?" + parse.urlencode(query_param_examples) # print request example - request_content = properties.get('requestBody', {}).get('content', {}) + request_content = properties.get("requestBody", {}).get("content", {}) for line in _example( - request_content, - method, - endpoint=endpoint_examples, - nb_indent=1): + request_content, method, endpoint=endpoint_examples, nb_indent=1 + ): yield line # print response status codes for status, response in responses.items(): - yield '{indent}:status {status}:'.format(**locals()) - for line in convert(response.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + yield "{indent}:status {status}:".format(**locals()) + for line in convert(response.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) # print response example if render_examples: for line in _example( - response.get('content', {}), status=status, nb_indent=2): + response.get("content", {}), status=status, nb_indent=2 + ): yield line # print request header params - for param in filter(lambda p: p['in'] == 'header', parameters): - yield indent + ':reqheader {name}:'.format(**param) - for line in convert(param.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) - if param.get('required', False): - yield '{indent}{indent}(Required)'.format(**locals()) + for param in filter(lambda p: p["in"] == "header", parameters): + yield indent + ":reqheader {name}:".format(**param) + for line in convert(param.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) + if param.get("required", False): + yield "{indent}{indent}(Required)".format(**locals()) # print response headers for status, response in responses.items(): - for headername, header in response.get('headers', {}).items(): - yield indent + ':resheader {name}:'.format(name=headername) - for line in convert(header.get('description', '')).splitlines(): - yield '{indent}{indent}{line}'.format(**locals()) + for headername, header in response.get("headers", {}).items(): + yield indent + f":resheader {headername}:" + for line in convert(header.get("description", "")).splitlines(): + yield "{indent}{indent}{line}".format(**locals()) - for cb_name, cb_specs in properties.get('callbacks', {}).items(): - yield '' - yield indent + '.. admonition:: Callback: ' + cb_name - yield '' + for cb_name, cb_specs in properties.get("callbacks", {}).items(): + yield "" + yield indent + ".. admonition:: Callback: " + cb_name + yield "" for cb_endpoint in cb_specs.keys(): for cb_method, cb_properties in cb_specs[cb_endpoint].items(): for line in _httpresource( - cb_endpoint, - cb_method, - cb_properties, - convert=convert, - render_examples=render_examples, - render_request=render_request): + cb_endpoint, + cb_method, + cb_properties, + convert=convert, + render_examples=render_examples, + render_request=render_request, + ): if line: - yield indent+indent+line + yield indent + indent + line else: - yield '' + yield "" - yield '' + yield "" def _header(title): yield title - yield '=' * len(title) - yield '' + yield "=" * len(title) + yield "" def openapihttpdomain(spec, **options): @@ -400,31 +400,31 @@ def openapihttpdomain(spec, **options): # If 'paths' are passed we've got to ensure they exist within an OpenAPI # spec; otherwise raise error and ask user to fix that. - if 'paths' in options: - if not set(options['paths']).issubset(spec['paths']): + if "paths" in options: + if not set(options["paths"]).issubset(spec["paths"]): raise ValueError( - 'One or more paths are not defined in the spec: %s.' % ( - ', '.join(set(options['paths']) - set(spec['paths'])), + "One or more paths are not defined in the spec: {}.".format( + ", ".join(set(options["paths"]) - set(spec["paths"])) ) ) - paths = options['paths'] + paths = options["paths"] # Check against regular expressions to be included - if 'include' in options: - for i in options['include']: + if "include" in options: + for i in options["include"]: ir = re.compile(i) - for path in spec['paths']: + for path in spec["paths"]: if ir.match(path): paths.append(path) # If no include nor paths option, then take full path - if 'include' not in options and 'paths' not in options: - paths = spec['paths'] + if "include" not in options and "paths" not in options: + paths = spec["paths"] # Remove paths matching regexp - if 'exclude' in options: + if "exclude" in options: _paths = [] - for e in options['exclude']: + for e in options["exclude"]: er = re.compile(e) for path in paths: if not er.match(path): @@ -432,44 +432,48 @@ def openapihttpdomain(spec, **options): paths = _paths render_request = False - if 'request' in options: + if "request" in options: render_request = True convert = utils.get_text_converter(options) # https://github.com/OAI/OpenAPI-Specification/blob/3.0.2/versions/3.0.0.md#paths-object - if 'group' in options: - groups = collections.OrderedDict( - [(x['name'], []) for x in spec.get('tags', {})] - ) + if "group" in options: + groups = {x["name"]: [] for x in spec.get("tags", {})} for endpoint in paths: - for method, properties in spec['paths'][endpoint].items(): - key = properties.get('tags', [''])[0] - groups.setdefault(key, []).append(_httpresource( - endpoint, - method, - properties, - convert, - render_examples='examples' in options, - render_request=render_request)) + for method, properties in spec["paths"][endpoint].items(): + key = properties.get("tags", [""])[0] + groups.setdefault(key, []).append( + _httpresource( + endpoint, + method, + properties, + convert, + render_examples="examples" in options, + render_request=render_request, + ) + ) for key in groups.keys(): if key: generators.append(_header(key)) else: - generators.append(_header('default')) + generators.append(_header("default")) generators.extend(groups[key]) else: for endpoint in paths: - for method, properties in spec['paths'][endpoint].items(): - generators.append(_httpresource( - endpoint, - method, - properties, - convert, - render_examples='examples' in options, - render_request=render_request)) + for method, properties in spec["paths"][endpoint].items(): + generators.append( + _httpresource( + endpoint, + method, + properties, + convert, + render_examples="examples" in options, + render_request=render_request, + ) + ) return iter(itertools.chain(*generators)) diff --git a/sphinxcontrib/openapi/openapi31.py b/sphinxcontrib/openapi/openapi31.py index 0e8cba7..d5bde44 100644 --- a/sphinxcontrib/openapi/openapi31.py +++ b/sphinxcontrib/openapi/openapi31.py @@ -86,7 +86,7 @@ def _parse_schema(schema, method): Convert a Schema Object to a Python object. Args: - schema: An ``OrderedDict`` representing the schema object. + schema: A dict representing the schema object. """ if method and schema.get("readOnly", False): return _READONLY_PROPERTY @@ -136,7 +136,7 @@ def _parse_schema(schema, method): "supported." ) - schema_type = [x for x in schema_type if x != "null"][0] + schema_type = next(x for x in schema_type if x != "null") if schema_type == "array": # special case oneOf and anyOf so that we can show examples for all @@ -157,13 +157,13 @@ def _parse_schema(schema, method): ): return _READONLY_PROPERTY - results = [] + results = {} for name, prop in schema.get("properties", {}).items(): result = _parse_schema(prop, method) if result != _READONLY_PROPERTY: - results.append((name, result)) + results[name] = result - return collections.OrderedDict(results) + return results if (schema_type, schema.get("format")) in _TYPE_MAPPING: return _TYPE_MAPPING[(schema_type, schema.get("format"))] @@ -282,8 +282,8 @@ def _httpresource( query_param_examples = [] indent = " " - yield ".. http:{0}:: {1}".format(method, endpoint) - yield " :synopsis: {0}".format(properties.get("summary", "null")) + yield f".. http:{method}:: {endpoint}" + yield " :synopsis: {}".format(properties.get("summary", "null")) yield "" if "summary" in properties: @@ -397,7 +397,7 @@ def _get_type_from_schema(schema): # print response headers for status, response in responses.items(): for headername, header in response.get("headers", {}).items(): - yield indent + ":resheader {name}:".format(name=headername) + yield indent + f":resheader {headername}:" for line in convert(header.get("description", "")).splitlines(): yield "{indent}{indent}{line}".format(**locals()) @@ -460,8 +460,9 @@ def openapihttpdomain(spec, **options): if "paths" in options: if not set(options["paths"]).issubset(spec["paths"]): raise ValueError( - "One or more paths are not defined in the spec: %s." - % (", ".join(set(options["paths"]) - set(spec["paths"])),) + "One or more paths are not defined in the spec: {}.".format( + ", ".join(set(options["paths"]) - set(spec["paths"])) + ) ) paths = options["paths"] @@ -493,9 +494,7 @@ def openapihttpdomain(spec, **options): # https://github.com/OAI/OpenAPI-Specification/blob/3.1.0/versions/3.1.0.md#paths-object if "group" in options: - groups = collections.OrderedDict( - [(x["name"], []) for x in spec.get("tags", {})] - ) + groups = {x["name"]: [] for x in spec.get("tags", {})} for endpoint in paths: for method, properties in spec["paths"][endpoint].items(): diff --git a/sphinxcontrib/openapi/renderers/__init__.py b/sphinxcontrib/openapi/renderers/__init__.py index 50ba599..63258e5 100644 --- a/sphinxcontrib/openapi/renderers/__init__.py +++ b/sphinxcontrib/openapi/renderers/__init__.py @@ -5,7 +5,7 @@ from ._httpdomain import HttpdomainRenderer __all__ = [ - "abc", "HttpdomainOldRenderer", "HttpdomainRenderer", + "abc", ] diff --git a/sphinxcontrib/openapi/renderers/_httpdomain.py b/sphinxcontrib/openapi/renderers/_httpdomain.py index 5118e15..bb0e514 100644 --- a/sphinxcontrib/openapi/renderers/_httpdomain.py +++ b/sphinxcontrib/openapi/renderers/_httpdomain.py @@ -317,7 +317,7 @@ def render_parameter(self, parameter): # According to OpenAPI v3 spec, 'content' in this case may # have one and only one entry. Hence casting its values to # list is not expensive and should be acceptable. - schema = list(parameter["content"].values())[0].get("schema", {}) + schema = next(iter(parameter["content"].values())).get("schema", {}) if parameter["in"] not in kinds: logger.warning( @@ -438,7 +438,9 @@ def render_response(self, status_code, response): # According to OpenAPI v3 spec, 'content' in this case may # have one and only one entry. Hence casting its values to # list is not expensive and should be acceptable. - schema = list(header_value["content"].values())[0].get("schema", {}) + schema = next(iter(header_value["content"].values())).get( + "schema", {} + ) markers = _get_markers_from_object(header_value, schema) if markers: diff --git a/sphinxcontrib/openapi/renderers/_httpdomain_old.py b/sphinxcontrib/openapi/renderers/_httpdomain_old.py index aaed143..1bcddae 100644 --- a/sphinxcontrib/openapi/renderers/_httpdomain_old.py +++ b/sphinxcontrib/openapi/renderers/_httpdomain_old.py @@ -50,6 +50,6 @@ def render_restructuredtext_markup(self, spec): elif spec_version.startswith("3.1."): openapihttpdomain = openapi31.openapihttpdomain else: - raise ValueError("Unsupported OpenAPI version (%s)" % spec_version) + raise ValueError(f"Unsupported OpenAPI version ({spec_version})") yield from openapihttpdomain(spec, **self._options) diff --git a/sphinxcontrib/openapi/schema_utils.py b/sphinxcontrib/openapi/schema_utils.py index eefb5b8..1ab2cee 100644 --- a/sphinxcontrib/openapi/schema_utils.py +++ b/sphinxcontrib/openapi/schema_utils.py @@ -29,25 +29,13 @@ def example_from_schema(schema): ... "type": "object", ... "required": ["id", "name"], ... "properties": { - ... "id": { - ... "type": "integer", - ... "format": "int64" - ... }, - ... "name": { - ... "type": "string", - ... "example": "John Smith" - ... }, - ... "tag": { - ... "type": "string" - ... } - ... } + ... "id": {"type": "integer", "format": "int64"}, + ... "name": {"type": "string", "example": "John Smith"}, + ... "tag": {"type": "string"}, + ... }, ... } >>> example = example_from_schema(schema) - >>> assert example == { - ... "id": 1, - ... "name": "John Smith", - ... "tag": "string" - ... } + >>> assert example == {"id": 1, "name": "John Smith", "tag": "string"} """ # If an example was provided then we use that if "example" in schema: @@ -83,7 +71,8 @@ def example_from_schema(schema): items = schema["items"] min_length = schema.get("minItems", 0) max_length = schema.get("maxItems", max(min_length, 2)) - assert min_length <= max_length + if min_length > max_length: + raise Exception("invalid minItems") # Try generate at least 2 example array items gen_length = min(2, max_length) if min_length <= 2 else min_length @@ -97,7 +86,8 @@ def example_from_schema(schema): else: example_items.append(example_from_schema(items)) - # Generate array containing example_items and satisfying min_length and max_length + # Generate array containing example_items and satisfying min_length and + # max_length return [example_items[i % len(example_items)] for i in range(gen_length)] elif schema["type"] == "string": @@ -111,7 +101,8 @@ def example_from_schema(schema): if min_length <= len(example_string) else min_length ) - assert 0 <= min_length <= max_length + if min_length < 0 or min_length > max_length: + raise Exception("invalid minLength") if min_length <= len(example_string) <= max_length: return example_string else: diff --git a/sphinxcontrib/openapi/utils.py b/sphinxcontrib/openapi/utils.py index daeedc2..ab7beea 100644 --- a/sphinxcontrib/openapi/utils.py +++ b/sphinxcontrib/openapi/utils.py @@ -1,15 +1,13 @@ """ - sphinxcontrib.openapi.utils - --------------------------- +sphinxcontrib.openapi.utils +--------------------------- - Common functionality shared across the various renderers. +Common functionality shared across the various renderers. - :copyright: (c) 2016, Ihor Kalnytskyi. - :license: BSD, see LICENSE for details. +:copyright: (c) 2016, Ihor Kalnytskyi. +:license: BSD, see LICENSE for details. """ -from __future__ import unicode_literals - import collections import collections.abc @@ -32,6 +30,7 @@ class OpenApiRefResolver(jsonschema.RefResolver): try: import requests + _requests = requests except ImportError: _requests = None @@ -41,9 +40,9 @@ def resolve_remote(self, uri): _, extension = os.path.splitext(path) if extension not in [".yml", ".yaml"] or scheme in self.handlers: - return super(OpenApiRefResolver, self).resolve_remote(uri) + return super().resolve_remote(uri) - if scheme in [u"http", u"https"] and self._requests: + if scheme in ["http", "https"] and self._requests: response = self._requests.get(uri) result = yaml.safe_load(response.content) else: @@ -74,12 +73,16 @@ def _resolve_refs(uri, spec): resolver = OpenApiRefResolver(uri, spec) def _do_resolve(node, seen=[]): - if isinstance(node, collections.abc.Mapping) and '$ref' in node: - ref = node['$ref'] + if isinstance(node, collections.abc.Mapping) and "$ref" in node: + ref = node["$ref"] with resolver.resolving(ref) as resolved: if ref in seen: - return {type: 'object'} # return a distinct object for recursive data type - return _do_resolve(resolved, seen + [ref]) # might have other references + return { + type: "object" + } # return a distinct object for recursive data type + return _do_resolve( + resolved, [*seen, ref] + ) # might have other references elif isinstance(node, collections.abc.Mapping): for k, v in node.items(): node[k] = _do_resolve(v, seen) @@ -96,23 +99,23 @@ def normalize_spec(spec, **options): # before we access the actual values trying to build an httpdomain # markup. Since JSON references may be relative, it's crucial to # pass a document URI in order to properly resolve them. - spec = _resolve_refs(options.get('uri', ''), spec) + spec = _resolve_refs(options.get("uri", ""), spec) # OpenAPI spec may contain common endpoint's parameters top-level. # In order to do not place if-s around the code to handle special # cases, let's normalize the spec and push common parameters inside # endpoints definitions. - for endpoint in spec.get('paths', {}).values(): - parameters = endpoint.pop('parameters', []) + for endpoint in spec.get("paths", {}).values(): + parameters = endpoint.pop("parameters", []) for method in endpoint.values(): - method.setdefault('parameters', []) - method['parameters'].extend(parameters) + method.setdefault("parameters", []) + method["parameters"].extend(parameters) def get_text_converter(options): """Decide on a text converter for prose.""" - if 'format' in options: - if options['format'] == 'markdown': + if "format" in options: + if options["format"] == "markdown": return sphinx_mdinclude.convert # No conversion needed. diff --git a/tests/conftest.py b/tests/conftest.py index d102a4a..07f8b8a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,9 @@ _testspecs_dir = pathlib.Path(os.path.dirname(__file__), "testspecs") -_testspecs = [str(path.relative_to(_testspecs_dir)) for path in _testspecs_dir.glob("*/*")] +_testspecs = [ + str(path.relative_to(_testspecs_dir)) for path in _testspecs_dir.glob("*/*") +] def pytest_addoption(parser): @@ -26,7 +28,8 @@ def pytest_collection_modifyitems(items): if any( [ item.config.getoption("--regenerate-rendered-specs") and has_mark, - not item.config.getoption("--regenerate-rendered-specs") and not has_mark, + not item.config.getoption("--regenerate-rendered-specs") + and not has_mark, ] ): items_new.append(item) @@ -36,22 +39,22 @@ def pytest_collection_modifyitems(items): def _format_option_raw(key, val): if isinstance(val, bool) and val: - return ':%s:' % key - return ':%s: %s' % (key, val) + return f":{key}:" + return f":{key}: {val}" -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def run_sphinx(tmpdir): - src = tmpdir.ensure('src', dir=True) - out = tmpdir.ensure('out', dir=True) + src = tmpdir.ensure("src", dir=True) + out = tmpdir.ensure("out", dir=True) def run(spec, options={}): - options_raw = '\n'.join([ - ' %s' % _format_option_raw(key, val) - for key, val in options.items()]) + options_raw = "\n".join( + [f" {_format_option_raw(key, val)}" for key, val in options.items()] + ) - src.join('conf.py').write_text( - textwrap.dedent(''' + src.join("conf.py").write_text( + textwrap.dedent(""" import os project = 'sphinxcontrib-openapi-test' @@ -60,19 +63,20 @@ def run(spec, options={}): extensions = ['sphinxcontrib.openapi'] source_suffix = '.rst' master_doc = 'index' - '''), - encoding='utf-8') + """), + encoding="utf-8", + ) - src.join('index.rst').write_text( - '.. openapi:: %s\n%s' % (spec, options_raw), - encoding='utf-8') + src.join("index.rst").write_text( + f".. openapi:: {spec}\n{options_raw}", encoding="utf-8" + ) Sphinx( srcdir=src.strpath, confdir=src.strpath, outdir=out.strpath, - doctreedir=out.join('.doctrees').strpath, - buildername='html' + doctreedir=out.join(".doctrees").strpath, + buildername="html", ).build() yield run @@ -86,6 +90,7 @@ def get_testspec(*args, encoding="utf-8", resolve_refs=True): if resolve_refs: spec = utils._resolve_refs("", spec) return spec + return get_testspec diff --git a/tests/lib2to3/test_convert.py b/tests/lib2to3/test_convert.py index c8e4950..f379ec3 100644 --- a/tests/lib2to3/test_convert.py +++ b/tests/lib2to3/test_convert.py @@ -4,7 +4,8 @@ def test_minimal(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -15,7 +16,8 @@ def test_minimal(oas_fragment): responses: '200': description: a response description - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: @@ -31,7 +33,8 @@ def test_minimal(oas_fragment): def test_complete(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -45,7 +48,8 @@ def test_complete(oas_fragment): responses: '200': description: a response description - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: @@ -236,7 +240,8 @@ def test_servers_schemes_from_operation(oas_fragment): def test_consumes(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -257,7 +262,8 @@ def test_consumes(oas_fragment): responses: '201': description: a response description - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: @@ -283,7 +289,8 @@ def test_consumes(oas_fragment): def test_consumes_operation_override(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -306,7 +313,8 @@ def test_consumes_operation_override(oas_fragment): responses: '201': description: a response description - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: @@ -332,7 +340,8 @@ def test_consumes_operation_override(oas_fragment): def test_produces(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -350,7 +359,8 @@ def test_produces(oas_fragment): type: integer type: array description: a response description - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: @@ -373,7 +383,8 @@ def test_produces(oas_fragment): def test_produces_operation_override(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -393,7 +404,8 @@ def test_produces_operation_override(oas_fragment): type: integer type: array description: a response description - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: @@ -416,7 +428,8 @@ def test_produces_operation_override(oas_fragment): def test_vendor_extensions(oas_fragment): - converted = lib2to3.convert(oas_fragment(""" + converted = lib2to3.convert( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -428,7 +441,8 @@ def test_vendor_extensions(oas_fragment): '200': description: a response description x-vendor-ext: vendor-ext - """)) + """) + ) assert converted == oas_fragment(""" openapi: 3.0.3 info: diff --git a/tests/lib2to3/test_convert_parameter.py b/tests/lib2to3/test_convert_parameter.py index 3dd5188..e8f1415 100644 --- a/tests/lib2to3/test_convert_parameter.py +++ b/tests/lib2to3/test_convert_parameter.py @@ -29,7 +29,8 @@ def _wrapper(parameter): def test_in_header_complete(convert_parameter, oas_fragment): - converted = convert_parameter(oas_fragment(""" + converted = convert_parameter( + oas_fragment(""" description: token to be passed as a header in: header items: @@ -38,7 +39,8 @@ def test_in_header_complete(convert_parameter, oas_fragment): name: token required: true type: array - """)) + """) + ) assert converted == oas_fragment(""" description: token to be passed as a header in: header diff --git a/tests/renderers/httpdomain/test_render_json_schema_description.py b/tests/renderers/httpdomain/test_render_json_schema_description.py index b9bc51c..7e57c5e 100644 --- a/tests/renderers/httpdomain/test_render_json_schema_description.py +++ b/tests/renderers/httpdomain/test_render_json_schema_description.py @@ -41,7 +41,8 @@ def test_render_json_schema_description_root_object( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} prop_a: :{typedirective} prop_a: string :{directive} prop_b: @@ -50,7 +51,8 @@ def test_render_json_schema_description_root_object( :{typedirective} prop_b.eggs: boolean :{directive} prop_c: :{typedirective} prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -78,10 +80,12 @@ def test_render_json_schema_description_root_array( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} prop: :{typedirective} prop: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -114,8 +118,10 @@ def test_render_json_schema_description_root_unsupported( req_or_res, ) ) - assert markup == textwrap.dedent("""\ - """.rstrip()) + assert markup == textwrap.dedent( + """\ + """.rstrip() + ) @pytest.mark.parametrize( @@ -151,12 +157,14 @@ def test_render_json_schema_description_root_any_of_object( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} prop_a: :{typedirective} prop_a: string :{directive} prop_b: :{typedirective} prop_b: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -191,10 +199,12 @@ def test_render_json_schema_description_root_any_of_array( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} prop: :{typedirective} prop: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -229,8 +239,10 @@ def test_render_json_schema_description_root_any_of_unsupported( req_or_res, ) ) - assert markup == textwrap.dedent("""\ - """.rstrip()) + assert markup == textwrap.dedent( + """\ + """.rstrip() + ) @pytest.mark.parametrize( @@ -266,12 +278,14 @@ def test_render_json_schema_description_root_one_of_object( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} prop_a: :{typedirective} prop_a: string :{directive} prop_b: :{typedirective} prop_b: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -306,10 +320,12 @@ def test_render_json_schema_description_root_one_of_array( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} prop: :{typedirective} prop: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -344,8 +360,10 @@ def test_render_json_schema_description_root_one_of_unsupported( req_or_res, ) ) - assert markup == textwrap.dedent("""\ - """.rstrip()) + assert markup == textwrap.dedent( + """\ + """.rstrip() + ) @pytest.mark.parametrize( @@ -380,7 +398,8 @@ def test_render_json_schema_description_root_all_of_object( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} name: :{typedirective} name: object :{directive} name.first: @@ -389,7 +408,8 @@ def test_render_json_schema_description_root_all_of_object( :{typedirective} name.last: string :{directive} age: :{typedirective} age: integer - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -425,10 +445,12 @@ def test_render_json_schema_description_primitive( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: {schema_type} - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -464,7 +486,8 @@ def test_render_json_schema_description_object( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: :{typedirective} root: object :{directive} root.prop_a: @@ -475,7 +498,8 @@ def test_render_json_schema_description_object( :{typedirective} root.prop_b.eggs: boolean :{directive} root.prop_c: :{typedirective} root.prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -509,7 +533,8 @@ def test_render_json_schema_description_object_implicit( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: :{typedirective} root: object :{directive} root.prop_a: @@ -520,7 +545,8 @@ def test_render_json_schema_description_object_implicit( :{typedirective} root.prop_b.eggs: boolean :{directive} root.prop_c: :{typedirective} root.prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -557,7 +583,8 @@ def test_render_json_schema_description_array( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root[]: :{typedirective} root[]: object :{directive} root[].prop_a: @@ -566,7 +593,8 @@ def test_render_json_schema_description_array( :{typedirective} root[].prop_b[]: number :{directive} root[].prop_c: :{typedirective} root[].prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -601,7 +629,8 @@ def test_render_json_schema_description_array_implicit( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root[]: :{typedirective} root[]: object :{directive} root[].prop_a: @@ -610,7 +639,8 @@ def test_render_json_schema_description_array_implicit( :{typedirective} root[].prop_b[]: number :{directive} root[].prop_c: :{typedirective} root[].prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -637,10 +667,12 @@ def test_render_json_schema_description_format( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} created_at: :{typedirective} created_at: string:date-time - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -667,10 +699,12 @@ def test_render_json_schema_description_deprecated( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} created_at: :{typedirective} created_at: string, deprecated - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -708,7 +742,8 @@ def test_render_json_schema_description_required( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: :{typedirective} root: object :{directive} root.prop_a: @@ -719,7 +754,8 @@ def test_render_json_schema_description_required( :{typedirective} root.prop_b.eggs: boolean, required :{directive} root.prop_c: :{typedirective} root.prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -732,7 +768,10 @@ def test_render_json_schema_description_required( def test_render_json_schema_description_deprecated_and_required( testrenderer, oas_fragment, req_or_res, directive, typedirective ): - """JSON schema description is generated for JSON object w/ deprecated & required markers.""" + """JSON schema description is generated for JSON object + + Deprecated & required markers should be included. + """ markup = textify( testrenderer.render_json_schema_description( @@ -758,7 +797,8 @@ def test_render_json_schema_description_deprecated_and_required( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: :{typedirective} root: object :{directive} root.prop_a: @@ -769,7 +809,8 @@ def test_render_json_schema_description_deprecated_and_required( :{typedirective} root.prop_b.eggs: boolean, deprecated, required :{directive} root.prop_c: :{typedirective} root.prop_c: number - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -797,11 +838,13 @@ def test_render_json_schema_description_description( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} created_at: a resource creation time :{typedirective} created_at: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -829,11 +872,13 @@ def test_render_json_schema_description_description_commonmark_default( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} created_at: a ``resource`` creation **time** :{typedirective} created_at: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -862,11 +907,13 @@ def test_render_json_schema_description_description_commonmark( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} created_at: a ``resource`` creation **time** :{typedirective} created_at: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -897,11 +944,13 @@ def test_render_json_schema_description_description_restructuredtext( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} created_at: a `resource` creation __time__ :{typedirective} created_at: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -918,7 +967,7 @@ def test_render_json_schema_description_any_of( markup = textify( testrenderer.render_json_schema_description( - oas_fragment(f""" + oas_fragment(""" type: object properties: some_key: @@ -929,10 +978,12 @@ def test_render_json_schema_description_any_of( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: integer - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -960,10 +1011,12 @@ def test_render_json_schema_description_one_of( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: integer - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1001,7 +1054,8 @@ def test_render_json_schema_description_all_of( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} person: :{typedirective} person: object :{directive} person.name: @@ -1012,7 +1066,8 @@ def test_render_json_schema_description_all_of( :{typedirective} person.name.last: string :{directive} person.age: :{typedirective} person.age: integer - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1040,10 +1095,12 @@ def test_render_json_schema_description_all_of_logical_impossible( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1072,10 +1129,12 @@ def test_render_json_schema_description_any_of_shared_type( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1104,10 +1163,12 @@ def test_render_json_schema_description_one_of_shared_type( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1136,10 +1197,12 @@ def test_render_json_schema_description_all_of_shared_type( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} some_key: :{typedirective} some_key: string - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1166,9 +1229,11 @@ def test_render_json_schema_description_not( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1197,10 +1262,12 @@ def test_render_json_schema_description_enum( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: :{typedirective} root: string:enum - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -1228,7 +1295,9 @@ def test_render_json_schema_description_enum_wo_type( req_or_res, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :{directive} root: :{typedirective} root: enum - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_operation.py b/tests/renderers/httpdomain/test_render_operation.py index 4855d00..78d05da 100644 --- a/tests/renderers/httpdomain/test_render_operation.py +++ b/tests/renderers/httpdomain/test_render_operation.py @@ -41,7 +41,8 @@ def test_render_operation(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:get:: /evidences/{evidenceId} **Retrieve an evidence by ID.** @@ -58,7 +59,8 @@ def test_render_operation(testrenderer, oas_fragment): An evidence. :statuscode 404: An evidence not found. - """.rstrip()) + """.rstrip() + ) def test_render_operation_minimal(testrenderer, oas_fragment): @@ -75,12 +77,14 @@ def test_render_operation_minimal(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_summary(testrenderer, oas_fragment): @@ -98,14 +102,16 @@ def test_render_operation_summary(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences **Create an evidence.** :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_description(testrenderer, oas_fragment): @@ -123,14 +129,16 @@ def test_render_operation_description(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences Create an evidence. :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_description_multiline(testrenderer, oas_fragment): @@ -150,7 +158,8 @@ def test_render_operation_description_multiline(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences Create @@ -158,7 +167,8 @@ def test_render_operation_description_multiline(testrenderer, oas_fragment): :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_description_commonmark_default(testrenderer, oas_fragment): @@ -176,14 +186,16 @@ def test_render_operation_description_commonmark_default(testrenderer, oas_fragm """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences **Create** an ``evidence``. :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_description_commonmark(fakestate, oas_fragment): @@ -202,14 +214,16 @@ def test_render_operation_description_commonmark(fakestate, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences **Create** an ``evidence``. :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_description_commonmark_restructuredtext( @@ -232,14 +246,16 @@ def test_render_operation_description_commonmark_restructuredtext( """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences __Create__ an `evidence`. :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_deprecated(testrenderer, oas_fragment): @@ -257,13 +273,15 @@ def test_render_operation_deprecated(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences :deprecated: :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) def test_render_operation_w_requestbody(testrenderer, oas_fragment): @@ -286,7 +304,8 @@ def test_render_operation_w_requestbody(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. http:post:: /evidences .. sourcecode:: http @@ -301,7 +320,8 @@ def test_render_operation_w_requestbody(testrenderer, oas_fragment): :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -327,7 +347,8 @@ def test_render_operation_caseinsensitive_method(testrenderer, method, oas_fragm """), ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ .. http:{method}:: /evidences .. sourcecode:: http @@ -342,4 +363,5 @@ def test_render_operation_caseinsensitive_method(testrenderer, method, oas_fragm :statuscode 201: An evidence created. - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_parameter.py b/tests/renderers/httpdomain/test_render_parameter.py index 64d7ae5..6434649 100644 --- a/tests/renderers/httpdomain/test_render_parameter.py +++ b/tests/renderers/httpdomain/test_render_parameter.py @@ -12,68 +12,92 @@ def textify(generator): def test_render_parameter_path(testrenderer, oas_fragment): """Usual path parameter's definition is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true description: A unique evidence identifier to query. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence identifier to query. :paramtype evidenceId: string, required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_minimal(testrenderer, oas_fragment): """Path parameter's minimal definition is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_description(testrenderer, oas_fragment): """Path parameter's 'description' is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true description: A unique evidence identifier to query. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence identifier to query. :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_multiline_description(testrenderer, oas_fragment): """Path parameter's multiline 'description' is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true description: | A unique evidence identifier to query. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence identifier to query. :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_description_commonmark_default( @@ -81,40 +105,52 @@ def test_render_parameter_path_description_commonmark_default( ): """Path parameter's 'description' must be in commonmark by default.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence ``identifier`` to **query**. :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_description_commonmark(fakestate, oas_fragment): """Path parameter's 'description' can be in commonmark.""" testrenderer = renderers.HttpdomainRenderer(fakestate, {"markup": "commonmark"}) - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence ``identifier`` to **query**. :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_description_restructuredtext(fakestate, oas_fragment): @@ -123,158 +159,218 @@ def test_render_parameter_path_description_restructuredtext(fakestate, oas_fragm testrenderer = renderers.HttpdomainRenderer( fakestate, {"markup": "restructuredtext"} ) - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence `identifier` to __query__. :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_deprecated(testrenderer, oas_fragment): """Path parameter's 'deprecated' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true deprecated: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: :paramtype evidenceId: required, deprecated - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_deprecated_false(testrenderer, oas_fragment): """Path parameter's 'deprecated' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path required: true deprecated: false - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: :paramtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_type(testrenderer, oas_fragment): """Path parameter's type is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: :paramtype evidenceId: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_type_with_format(testrenderer, oas_fragment): """Path parameter's type with format is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path schema: type: string format: uuid4 - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: :paramtype evidenceId: string:uuid4 - """.rstrip()) + """.rstrip() + ) def test_render_parameter_path_type_from_content(testrenderer, oas_fragment): """Path parameter's type from content is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path content: text/plain: schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: :paramtype evidenceId: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query(testrenderer, oas_fragment): """Usual query parameter's definition is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path description: A unique evidence identifier to query. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence identifier to query. :paramtype evidenceId: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_minimal(testrenderer, oas_fragment): """Query parameter's minimal definition is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: path - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_description(testrenderer, oas_fragment): """Query parameter's 'description' is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query description: A unique evidence identifier to query. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: A unique evidence identifier to query. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_multiline_description(testrenderer, oas_fragment): """Query parameter's multiline 'description' is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query description: | A unique evidence identifier to query. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: A unique evidence identifier to query. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_description_commonmark_default( @@ -282,36 +378,48 @@ def test_render_parameter_query_description_commonmark_default( ): """Query parameter's 'description' must be in commonmark by default.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: A unique evidence ``identifier`` to **query**. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_description_commonmark(fakestate, oas_fragment): """Query parameter's 'description' can be in commonmark.""" testrenderer = renderers.HttpdomainRenderer(fakestate, {"markup": "commonmark"}) - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: A unique evidence ``identifier`` to **query**. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_description_restructuredtext(fakestate, oas_fragment): @@ -320,195 +428,273 @@ def test_render_parameter_query_description_restructuredtext(fakestate, oas_frag testrenderer = renderers.HttpdomainRenderer( fakestate, {"markup": "restructuredtext"} ) - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: A unique evidence `identifier` to __query__. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_required(testrenderer, oas_fragment): """Query parameter's 'required' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query required: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: :queryparamtype evidenceId: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_required_false(testrenderer, oas_fragment): """Query parameter's 'required' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query required: false - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_deprecated(testrenderer, oas_fragment): """Query parameter's 'deprecated' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query deprecated: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: :queryparamtype evidenceId: deprecated - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_deprecated_false(testrenderer, oas_fragment): """Query parameter's 'deprecated' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query deprecated: false - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_required_deprecated(testrenderer, oas_fragment): """Both query parameter's markers are rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query required: true deprecated: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: :queryparamtype evidenceId: required, deprecated - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_type(testrenderer, oas_fragment): """Query parameter's type is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: :queryparamtype evidenceId: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_type_with_format(testrenderer, oas_fragment): """Query parameter's type with format is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query schema: type: string format: uuid4 - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: :queryparamtype evidenceId: string:uuid4 - """.rstrip()) + """.rstrip() + ) def test_render_parameter_query_type_from_content(testrenderer, oas_fragment): """Query parameter's type from content is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: query content: text/plain: schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam evidenceId: :queryparamtype evidenceId: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header(testrenderer, oas_fragment): """Usual header parameter's definition is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header description: A unique request identifier. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: A unique request identifier. :reqheadertype X-Request-Id: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_minimal(testrenderer, oas_fragment): """Header parameter's minimal definition is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_description(testrenderer, oas_fragment): """Header parameter's 'description' is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header description: A unique request identifier. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: A unique request identifier. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_multiline_description(testrenderer, oas_fragment): """Header parameter's multiline 'description' is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header description: | A unique request identifier. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: A unique request identifier. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_description_commonmark_default( @@ -516,36 +702,48 @@ def test_render_parameter_header_description_commonmark_default( ): """Header parameter's 'description' must be in commonmark by default.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: header description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader evidenceId: A unique evidence ``identifier`` to **query**. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_description_commonmark(fakestate, oas_fragment): """Header parameter's 'description' can be in commonmark.""" testrenderer = renderers.HttpdomainRenderer(fakestate, {"markup": "commonmark"}) - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: header description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader evidenceId: A unique evidence ``identifier`` to **query**. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_description_restructuredtext(fakestate, oas_fragment): @@ -554,132 +752,186 @@ def test_render_parameter_header_description_restructuredtext(fakestate, oas_fra testrenderer = renderers.HttpdomainRenderer( fakestate, {"markup": "restructuredtext"} ) - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: header description: | A unique evidence `identifier` to __query__. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader evidenceId: A unique evidence `identifier` to __query__. - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_required(testrenderer, oas_fragment): """Header parameter's 'required' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header required: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: :reqheadertype X-Request-Id: required - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_required_false(testrenderer, oas_fragment): """Header parameter's 'required' marker is not rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header required: false - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_deprecated(testrenderer, oas_fragment): """Header parameter's 'deprecated' marker is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header deprecated: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: :reqheadertype X-Request-Id: deprecated - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_deprecated_false(testrenderer, oas_fragment): """Header parameter's 'deprecated' marker is not rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header deprecated: false - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_required_deprecated(testrenderer, oas_fragment): """Both header parameter's markers are rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: X-Request-Id in: header required: true deprecated: true - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader X-Request-Id: :reqheadertype X-Request-Id: required, deprecated - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_type(testrenderer, oas_fragment): """Header parameter's type is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: header schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader evidenceId: :reqheadertype evidenceId: string - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_type_with_format(testrenderer, oas_fragment): """Header parameter's type with format is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: header schema: type: string format: uuid4 - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader evidenceId: :reqheadertype evidenceId: string:uuid4 - """.rstrip()) + """.rstrip() + ) def test_render_parameter_header_type_from_content(testrenderer, oas_fragment): """Header parameter's type from content is rendered.""" - markup = textify(testrenderer.render_parameter(oas_fragment(""" + markup = textify( + testrenderer.render_parameter( + oas_fragment(""" name: evidenceId in: header content: text/plain: schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader evidenceId: :reqheadertype evidenceId: string - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_parameters.py b/tests/renderers/httpdomain/test_render_parameters.py index 79701fe..ee53056 100644 --- a/tests/renderers/httpdomain/test_render_parameters.py +++ b/tests/renderers/httpdomain/test_render_parameters.py @@ -15,34 +15,46 @@ def textify(generator): def test_render_parameters_no_items(testrenderer, oas_fragment): """No parameter definitions are rendered.""" - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" [] - """))) + """) + ) + ) assert markup == "" def test_render_parameters_one_item(testrenderer, oas_fragment): """One usual parameter definition is rendered.""" - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" - name: evidenceId in: path required: true description: A unique evidence identifier to query. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :param evidenceId: A unique evidence identifier to query. :paramtype evidenceId: string, required - """.rstrip()) + """.rstrip() + ) def test_render_parameters_many_items(testrenderer, oas_fragment): """Many parameter definitions are rendered.""" - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" - name: evidenceId in: path required: true @@ -60,8 +72,11 @@ def test_render_parameters_many_items(testrenderer, oas_fragment): description: API version to use for the request. schema: type: integer - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader Api-Version: API version to use for the request. :reqheadertype Api-Version: integer @@ -71,7 +86,8 @@ def test_render_parameters_many_items(testrenderer, oas_fragment): :queryparam details: If true, information w/ details is returned. :queryparamtype details: boolean - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize("permutation_seq", itertools.permutations(range(3))) @@ -110,7 +126,8 @@ def test_render_parameters_many_items_ordered( ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :reqheader Api-Version: API version to use for the request. :reqheadertype Api-Version: integer @@ -120,13 +137,16 @@ def test_render_parameters_many_items_ordered( :queryparam details: If true, information w/ details is returned. :queryparamtype details: boolean - """.rstrip()) + """.rstrip() + ) def test_render_parameters_many_items_stable_order(testrenderer, oas_fragment): """Many parameter definitions are rendered w/ preserved order.""" - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" - name: kind in: path required: true @@ -161,8 +181,11 @@ def test_render_parameters_many_items_stable_order(testrenderer, oas_fragment): description: A desired Content-Type of HTTP response. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :reqheader Api-Version: API version to use for the request. :reqheadertype Api-Version: integer @@ -181,7 +204,8 @@ def test_render_parameters_many_items_stable_order(testrenderer, oas_fragment): :queryparam related: If true, links to related evidences are returned. :queryparamtype related: boolean - """.rstrip()) + """.rstrip() + ) def test_render_parameters_custom_order(fakestate, oas_fragment): @@ -191,7 +215,9 @@ def test_render_parameters_custom_order(fakestate, oas_fragment): fakestate, {"request-parameters-order": ["query", "path", "header"]} ) - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" - name: kind in: path required: true @@ -226,8 +252,11 @@ def test_render_parameters_custom_order(fakestate, oas_fragment): description: A desired Content-Type of HTTP response. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam details: If true, information w/ details is returned. :queryparamtype details: boolean @@ -246,7 +275,8 @@ def test_render_parameters_custom_order(fakestate, oas_fragment): :reqheader Accept: A desired Content-Type of HTTP response. :reqheadertype Accept: string - """.rstrip()) + """.rstrip() + ) def test_render_parameters_custom_order_partial(fakestate, oas_fragment): @@ -256,7 +286,9 @@ def test_render_parameters_custom_order_partial(fakestate, oas_fragment): fakestate, {"request-parameters-order": ["query", "path"]} ) - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" - name: kind in: path required: true @@ -291,8 +323,11 @@ def test_render_parameters_custom_order_partial(fakestate, oas_fragment): description: A desired Content-Type of HTTP response. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam details: If true, information w/ details is returned. :queryparamtype details: boolean @@ -311,7 +346,8 @@ def test_render_parameters_custom_order_partial(fakestate, oas_fragment): :reqheader Accept: A desired Content-Type of HTTP response. :reqheadertype Accept: string - """.rstrip()) + """.rstrip() + ) def test_render_parameters_case_insensitive(fakestate, oas_fragment): @@ -321,7 +357,9 @@ def test_render_parameters_case_insensitive(fakestate, oas_fragment): fakestate, {"request-parameters-order": ["QUERY", "pAth", "Header"]} ) - markup = textify(testrenderer.render_parameters(oas_fragment(""" + markup = textify( + testrenderer.render_parameters( + oas_fragment(""" - name: kind in: PATH required: true @@ -356,8 +394,11 @@ def test_render_parameters_case_insensitive(fakestate, oas_fragment): description: A desired Content-Type of HTTP response. schema: type: string - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :queryparam details: If true, information w/ details is returned. :queryparamtype details: boolean @@ -376,4 +417,5 @@ def test_render_parameters_case_insensitive(fakestate, oas_fragment): :reqheader Accept: A desired Content-Type of HTTP response. :reqheadertype Accept: string - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_paths.py b/tests/renderers/httpdomain/test_render_paths.py index c4f727d..d5bde8a 100644 --- a/tests/renderers/httpdomain/test_render_paths.py +++ b/tests/renderers/httpdomain/test_render_paths.py @@ -12,7 +12,9 @@ def textify(generator): def test_render_paths(testrenderer, oas_fragment): """Usual paths definition is rendered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences/{evidenceId}: summary: Ignored description: Ignored @@ -39,7 +41,9 @@ def test_render_paths(testrenderer, oas_fragment): description: An evidence. '404': description: An evidence not found. - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences/{evidenceId} @@ -63,13 +67,17 @@ def test_render_paths(testrenderer, oas_fragment): def test_render_paths_minimal(testrenderer, oas_fragment): """Minimal paths definition is rendered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences: get: responses: '200': description: A list of evidences. - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences @@ -81,7 +89,9 @@ def test_render_paths_minimal(testrenderer, oas_fragment): def test_render_paths_multiple(testrenderer, oas_fragment): """Paths definition with multiple paths is rendered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences/{evidenceId}: get: summary: Retrieve an evidence by ID. @@ -109,7 +119,9 @@ def test_render_paths_multiple(testrenderer, oas_fragment): responses: '201': description: An evidence created. - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences/{evidenceId} @@ -140,7 +152,9 @@ def test_render_paths_multiple(testrenderer, oas_fragment): def test_render_paths_parameters_common(testrenderer, oas_fragment): """Paths definition with common parameters is rendered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences/{evidenceId}: get: summary: Retrieve an evidence by ID. @@ -169,7 +183,9 @@ def test_render_paths_parameters_common(testrenderer, oas_fragment): description: A unique evidence identifier to query. schema: type: string - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences/{evidenceId} @@ -203,7 +219,9 @@ def test_render_paths_parameters_common(testrenderer, oas_fragment): def test_render_paths_parameters_common_prepend(testrenderer, oas_fragment): """Paths definition with common parameters is rendered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences/{evidenceId}/{evidenceSection}: get: summary: Retrieve an evidence by ID. @@ -225,7 +243,9 @@ def test_render_paths_parameters_common_prepend(testrenderer, oas_fragment): description: A unique evidence identifier to query. schema: type: string - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences/{evidenceId}/{evidenceSection} @@ -247,7 +267,9 @@ def test_render_paths_parameters_common_prepend(testrenderer, oas_fragment): def test_render_paths_parameters_common_overwritten(testrenderer, oas_fragment): """Paths definition with common parameters is rendered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences/{evidenceId}: get: summary: Retrieve an evidence by ID. @@ -267,7 +289,9 @@ def test_render_paths_parameters_common_overwritten(testrenderer, oas_fragment): description: A unique evidence identifier to query. schema: type: string - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences/{evidenceId} @@ -284,7 +308,9 @@ def test_render_paths_parameters_common_overwritten(testrenderer, oas_fragment): def test_render_paths_methods_order(testrenderer, oas_fragment): """Paths definition is rendered with HTTP methods ordered.""" - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences: post: responses: @@ -298,7 +324,9 @@ def test_render_paths_methods_order(testrenderer, oas_fragment): responses: '200': description: A list of evidences. - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:post:: /evidences @@ -324,7 +352,9 @@ def test_render_paths_methods_order_custom(fakestate, oas_fragment): fakestate, {"http-methods-order": ["delete", "options", "get", "post"]} ) - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences: post: responses: @@ -338,7 +368,9 @@ def test_render_paths_methods_order_custom(fakestate, oas_fragment): responses: '200': description: A list of evidences. - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:options:: /evidences @@ -364,7 +396,9 @@ def test_render_paths_methods_order_insensitive(fakestate, oas_fragment): fakestate, {"http-methods-order": ["gEt", "post"]} ) - markup = textify(testrenderer.render_paths(oas_fragment(""" + markup = textify( + testrenderer.render_paths( + oas_fragment(""" /evidences: post: responses: @@ -374,7 +408,9 @@ def test_render_paths_methods_order_insensitive(fakestate, oas_fragment): responses: '200': description: A list of evidences. - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /evidences diff --git a/tests/renderers/httpdomain/test_render_request_body_example.py b/tests/renderers/httpdomain/test_render_request_body_example.py index 56aa59a..1eb470e 100644 --- a/tests/renderers/httpdomain/test_render_request_body_example.py +++ b/tests/renderers/httpdomain/test_render_request_body_example.py @@ -127,7 +127,8 @@ def test_render_request_body_example(testrenderer, content, oas_fragment): "POST", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -137,7 +138,8 @@ def test_render_request_body_example(testrenderer, content, oas_fragment): "foo": "bar", "baz": 42 } - """.rstrip()) + """.rstrip() + ) def test_render_request_body_example_1st_from_examples(testrenderer, oas_fragment): @@ -161,7 +163,8 @@ def test_render_request_body_example_1st_from_examples(testrenderer, oas_fragmen "POST", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -171,7 +174,8 @@ def test_render_request_body_example_1st_from_examples(testrenderer, oas_fragmen "foo": "bar", "baz": 42 } - """.rstrip()) + """.rstrip() + ) def test_render_request_body_example_1st_from_media_type(testrenderer, oas_fragment): @@ -194,7 +198,8 @@ def test_render_request_body_example_1st_from_media_type(testrenderer, oas_fragm ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -202,7 +207,8 @@ def test_render_request_body_example_1st_from_media_type(testrenderer, oas_fragm foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -236,7 +242,8 @@ def test_render_request_body_example_preference( ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -244,7 +251,8 @@ def test_render_request_body_example_preference( foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -281,7 +289,8 @@ def test_render_request_body_example_preference_complex( ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -289,7 +298,8 @@ def test_render_request_body_example_preference_complex( foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) def test_render_request_body_example_preference_priority(fakestate, oas_fragment): @@ -321,7 +331,8 @@ def test_render_request_body_example_preference_priority(fakestate, oas_fragment ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -329,7 +340,8 @@ def test_render_request_body_example_preference_priority(fakestate, oas_fragment foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) @responses.activate @@ -356,14 +368,16 @@ def test_render_request_body_example_external(testrenderer, oas_fragment): "POST", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 Content-Type: application/json {"foo": "bar", "baz": 42} - """.rstrip()) + """.rstrip() + ) @responses.activate @@ -393,14 +407,16 @@ def test_render_request_body_example_external_errored_next_example( "POST", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 Content-Type: application/json {"spam": 42} - """.rstrip()) + """.rstrip() + ) @responses.activate @@ -432,14 +448,16 @@ def test_render_request_body_example_external_errored_next_media_type( "POST", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 Content-Type: text/csv spam,42 - """.rstrip()) + """.rstrip() + ) def test_render_request_body_example_content_type(testrenderer, oas_fragment): @@ -458,7 +476,8 @@ def test_render_request_body_example_content_type(testrenderer, oas_fragment): "POST", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http POST /evidences/{evidenceId} HTTP/1.1 @@ -466,7 +485,8 @@ def test_render_request_body_example_content_type(testrenderer, oas_fragment): foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) def test_render_request_body_example_noop(testrenderer, oas_fragment): @@ -512,7 +532,8 @@ def test_render_request_body_example_http_method( ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ .. sourcecode:: http {http_method} /evidences/{{evidenceId}} HTTP/1.1 @@ -520,7 +541,8 @@ def test_render_request_body_example_http_method( foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -548,7 +570,8 @@ def test_render_request_body_example_http_endpoint( ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ .. sourcecode:: http POST {http_endpoint} HTTP/1.1 @@ -556,4 +579,5 @@ def test_render_request_body_example_http_endpoint( foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_response.py b/tests/renderers/httpdomain/test_render_response.py index 37d1af8..b9972ad 100644 --- a/tests/renderers/httpdomain/test_render_response.py +++ b/tests/renderers/httpdomain/test_render_response.py @@ -30,10 +30,13 @@ def test_render_response_status_code(testrenderer, oas_fragment, statuscode): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode %s: An evidence. - """.rstrip() % statuscode) + """.rstrip() + % statuscode + ) def test_render_response_minimal(testrenderer, oas_fragment): @@ -47,10 +50,12 @@ def test_render_response_minimal(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. - """.rstrip()) + """.rstrip() + ) def test_render_response_description_commonmark_default(testrenderer, oas_fragment): @@ -66,11 +71,13 @@ def test_render_response_description_commonmark_default(testrenderer, oas_fragme """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An **evidence** that matches the ``query``. - """.rstrip()) + """.rstrip() + ) def test_render_response_description_commonmark(fakestate, oas_fragment): @@ -87,11 +94,13 @@ def test_render_response_description_commonmark(fakestate, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An **evidence** that matches the ``query``. - """.rstrip()) + """.rstrip() + ) def test_render_response_description_restructuredtext(fakestate, oas_fragment): @@ -110,11 +119,13 @@ def test_render_response_description_restructuredtext(fakestate, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An __evidence__ that matches the `query`. - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -141,7 +152,8 @@ def test_render_response_content_2xx(testrenderer, oas_fragment, status_code, st """), ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :statuscode {status_code}: An evidence. @@ -154,7 +166,8 @@ def test_render_response_content_2xx(testrenderer, oas_fragment, status_code, st "foo": "bar", "baz": 42 }} - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -183,10 +196,12 @@ def test_render_response_content_non_2xx(testrenderer, oas_fragment, status_code """), ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :statuscode {status_code}: An evidence. - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -218,7 +233,8 @@ def test_render_response_content_custom(fakestate, oas_fragment, status_code, st """), ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ :statuscode {status_code}: An evidence. @@ -231,7 +247,8 @@ def test_render_response_content_custom(fakestate, oas_fragment, status_code, st "foo": "bar", "baz": 42 }} - """.rstrip()) + """.rstrip() + ) def test_render_response_content_custom_mismatch(fakestate, oas_fragment): @@ -254,10 +271,12 @@ def test_render_response_content_custom_mismatch(fakestate, oas_fragment): """), ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. - """.rstrip()) + """.rstrip() + ) def test_render_response_header(testrenderer, oas_fragment): @@ -276,14 +295,16 @@ def test_render_response_header(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: A unique request identifier. :resheadertype X-Request-Id: string - """.rstrip()) + """.rstrip() + ) def test_render_response_header_minimal(testrenderer, oas_fragment): @@ -299,12 +320,14 @@ def test_render_response_header_minimal(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: - """.rstrip()) + """.rstrip() + ) def test_render_response_header_description(testrenderer, oas_fragment): @@ -321,13 +344,15 @@ def test_render_response_header_description(testrenderer, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: A unique request identifier. - """.rstrip()) + """.rstrip() + ) def test_render_response_header_multiline_description(testrenderer, oas_fragment): @@ -346,14 +371,16 @@ def test_render_response_header_multiline_description(testrenderer, oas_fragment """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: A unique request identifier. - """.rstrip()) + """.rstrip() + ) def test_render_response_header_description_commonmark_default( @@ -374,14 +401,16 @@ def test_render_response_header_description_commonmark_default( """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: A unique **request** ``identifier``. - """.rstrip()) + """.rstrip() + ) def test_render_response_header_description_commonmark(fakestate, oas_fragment): @@ -401,14 +430,16 @@ def test_render_response_header_description_commonmark(fakestate, oas_fragment): """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: A unique **request** ``identifier``. - """.rstrip()) + """.rstrip() + ) def test_render_response_header_description_restructuredtext(fakestate, oas_fragment): @@ -430,14 +461,16 @@ def test_render_response_header_description_restructuredtext(fakestate, oas_frag """), ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: A unique __request__ `identifier`. - """.rstrip()) + """.rstrip() + ) def test_render_response_header_content_type(testrenderer, oas_fragment): @@ -456,11 +489,13 @@ def test_render_response_header_content_type(testrenderer, oas_fragment): # There's an extra newline at the end of markup if there's at least one # response header defined. - assert markup.rstrip() == textwrap.dedent("""\ + assert markup.rstrip() == textwrap.dedent( + """\ :statuscode 200: An evidence. - """.rstrip()) + """.rstrip() + ) def test_render_response_header_required(testrenderer, oas_fragment): @@ -478,13 +513,15 @@ def test_render_response_header_required(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: :resheadertype X-Request-Id: required - """.rstrip()) + """.rstrip() + ) def test_render_response_header_required_false(testrenderer, oas_fragment): @@ -502,12 +539,14 @@ def test_render_response_header_required_false(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: - """.rstrip()) + """.rstrip() + ) def test_render_response_header_deprecated(testrenderer, oas_fragment): @@ -525,13 +564,15 @@ def test_render_response_header_deprecated(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: :resheadertype X-Request-Id: deprecated - """.rstrip()) + """.rstrip() + ) def test_render_response_header_deprecated_false(testrenderer, oas_fragment): @@ -549,12 +590,14 @@ def test_render_response_header_deprecated_false(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: - """.rstrip()) + """.rstrip() + ) def test_render_response_header_required_deprecated(testrenderer, oas_fragment): @@ -573,13 +616,15 @@ def test_render_response_header_required_deprecated(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: :resheadertype X-Request-Id: required, deprecated - """.rstrip()) + """.rstrip() + ) def test_render_response_header_type(testrenderer, oas_fragment): @@ -598,13 +643,15 @@ def test_render_response_header_type(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: :resheadertype X-Request-Id: string - """.rstrip()) + """.rstrip() + ) def test_render_response_header_type_with_format(testrenderer, oas_fragment): @@ -624,13 +671,15 @@ def test_render_response_header_type_with_format(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: :resheadertype X-Request-Id: string:uuid4 - """.rstrip()) + """.rstrip() + ) def test_render_response_header_type_from_content(testrenderer, oas_fragment): @@ -651,10 +700,12 @@ def test_render_response_header_type_from_content(testrenderer, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :resheader X-Request-Id: :resheadertype X-Request-Id: string - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_response_example.py b/tests/renderers/httpdomain/test_render_response_example.py index 86cad42..566d1f3 100644 --- a/tests/renderers/httpdomain/test_render_response_example.py +++ b/tests/renderers/httpdomain/test_render_response_example.py @@ -121,7 +121,8 @@ def test_render_response_example(testrenderer, oas_fragment, media_type): markup = textify( testrenderer.render_response_example(oas_fragment(media_type), "200") ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -131,7 +132,8 @@ def test_render_response_example(testrenderer, oas_fragment, media_type): "foo": "bar", "baz": 42 } - """.rstrip()) + """.rstrip() + ) def test_render_response_example_1st_from_examples(testrenderer, oas_fragment): @@ -153,7 +155,8 @@ def test_render_response_example_1st_from_examples(testrenderer, oas_fragment): "200", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -163,7 +166,8 @@ def test_render_response_example_1st_from_examples(testrenderer, oas_fragment): "foo": "bar", "baz": 42 } - """.rstrip()) + """.rstrip() + ) def test_render_response_example_1st_from_media_type(testrenderer, oas_fragment): @@ -184,7 +188,8 @@ def test_render_response_example_1st_from_media_type(testrenderer, oas_fragment) ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -192,7 +197,8 @@ def test_render_response_example_1st_from_media_type(testrenderer, oas_fragment) foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -224,7 +230,8 @@ def test_render_response_example_preference( ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -232,7 +239,8 @@ def test_render_response_example_preference( foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -267,7 +275,8 @@ def test_render_response_example_preference_complex( ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -275,7 +284,8 @@ def test_render_response_example_preference_complex( foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) def test_render_response_example_preference_priority(fakestate, oas_fragment): @@ -305,7 +315,8 @@ def test_render_response_example_preference_priority(fakestate, oas_fragment): ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -313,7 +324,8 @@ def test_render_response_example_preference_priority(fakestate, oas_fragment): foo = "bar" baz = 42 - """.rstrip()) + """.rstrip() + ) @responses.activate @@ -338,14 +350,16 @@ def test_render_response_example_external(testrenderer, oas_fragment): "200", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json {"foo": "bar", "baz": 42} - """.rstrip()) + """.rstrip() + ) @responses.activate @@ -373,14 +387,16 @@ def test_render_response_example_external_errored_next_example( "200", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json {"spam": 42} - """.rstrip()) + """.rstrip() + ) @responses.activate @@ -408,14 +424,16 @@ def test_render_response_example_external_errored_next_media_type( "200", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK Content-Type: text/csv spam,42 - """.rstrip()) + """.rstrip() + ) def test_render_response_example_content_type(testrenderer, oas_fragment): @@ -432,7 +450,8 @@ def test_render_response_example_content_type(testrenderer, oas_fragment): "200", ) ) - assert markup == textwrap.dedent("""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 200 OK @@ -440,7 +459,8 @@ def test_render_response_example_content_type(testrenderer, oas_fragment): foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) def test_render_response_example_noop(testrenderer, oas_fragment): @@ -484,7 +504,8 @@ def test_render_response_status_code( status_code, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ .. sourcecode:: http HTTP/1.1 {status_code} {status_text} @@ -492,7 +513,8 @@ def test_render_response_status_code( foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -519,7 +541,8 @@ def test_render_response_status_code_range( status_range, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ .. sourcecode:: http HTTP/1.1 {status_code} {status_text} @@ -527,7 +550,8 @@ def test_render_response_status_code_range( foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) @pytest.mark.parametrize( @@ -554,7 +578,8 @@ def test_render_response_status_code_int( status_code, ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + f"""\ .. sourcecode:: http HTTP/1.1 {status_code} {status_text} @@ -562,7 +587,8 @@ def test_render_response_status_code_int( foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) def test_render_response_status_code_default(testrenderer, oas_fragment): @@ -579,7 +605,8 @@ def test_render_response_status_code_default(testrenderer, oas_fragment): "default", ) ) - assert markup == textwrap.dedent(f"""\ + assert markup == textwrap.dedent( + """\ .. sourcecode:: http HTTP/1.1 000 Reason-Phrase @@ -587,4 +614,5 @@ def test_render_response_status_code_default(testrenderer, oas_fragment): foo,baz bar,42 - """.rstrip()) + """.rstrip() + ) diff --git a/tests/renderers/httpdomain/test_render_responses.py b/tests/renderers/httpdomain/test_render_responses.py index 6b4460f..6508261 100644 --- a/tests/renderers/httpdomain/test_render_responses.py +++ b/tests/renderers/httpdomain/test_render_responses.py @@ -12,59 +12,83 @@ def textify(generator): def test_render_responses_no_items(testrenderer, oas_fragment): """No response definitions are rendered.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" {} - """))) + """) + ) + ) assert markup == "" def test_render_responses_one_item(testrenderer, oas_fragment): """One usual response definition is rendered.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" '200': description: An evidence. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. - """.rstrip()) + """.rstrip() + ) def test_render_responses_one_item_status_code_int(testrenderer, oas_fragment): """One usual response definition is rendered even if status code is integer.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" 200: description: An evidence. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. - """.rstrip()) + """.rstrip() + ) def test_render_responses_many_items(testrenderer, oas_fragment): """Many response definitions are rendered.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" '200': description: An evidence. '404': description: An evidence not found. - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :statuscode 200: An evidence. :statuscode 404: An evidence not found. - """.rstrip()) + """.rstrip() + ) def test_render_responses_json_schema_description(testrenderer, oas_fragment): """JSON schema description is rendered.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" '200': description: An evidence. content: @@ -75,7 +99,9 @@ def test_render_responses_json_schema_description(testrenderer, oas_fragment): type: string bar: type: integer - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ :resjson foo: :resjsonobj foo: string @@ -90,7 +116,9 @@ def test_render_responses_json_schema_description(testrenderer, oas_fragment): def test_render_responses_json_schema_description_4xx(testrenderer, oas_fragment): """JSON schema description is rendered.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" '400': description: An evidence. content: @@ -101,17 +129,23 @@ def test_render_responses_json_schema_description_4xx(testrenderer, oas_fragment type: string bar: type: integer - """))) - assert markup == textwrap.dedent("""\ + """) + ) + ) + assert markup == textwrap.dedent( + """\ :statuscode 400: An evidence. - """.rstrip()) + """.rstrip() + ) def test_render_responses_json_schema_description_first_2xx(testrenderer, oas_fragment): """JSON schema description is rendered.""" - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" '400': description: An error. content: @@ -138,7 +172,9 @@ def test_render_responses_json_schema_description_first_2xx(testrenderer, oas_fr properties: bbb: type: string - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ :resjson foo: :resjsonobj foo: string @@ -163,7 +199,9 @@ def test_render_responses_json_schema_description_turned_off(fakestate, oas_frag {"no-json-schema-description": True}, ) - markup = textify(testrenderer.render_responses(oas_fragment(""" + markup = textify( + testrenderer.render_responses( + oas_fragment(""" '200': description: An evidence. content: @@ -174,7 +212,9 @@ def test_render_responses_json_schema_description_turned_off(fakestate, oas_frag type: string bar: type: integer - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ :statuscode 200: An evidence. diff --git a/tests/renderers/httpdomain/test_render_restructuredtext_markup.py b/tests/renderers/httpdomain/test_render_restructuredtext_markup.py index a984ccf..4b06a52 100644 --- a/tests/renderers/httpdomain/test_render_restructuredtext_markup.py +++ b/tests/renderers/httpdomain/test_render_restructuredtext_markup.py @@ -12,7 +12,9 @@ def textify(generator): def test_oas2_minimal(testrenderer, oas_fragment): """Minimal OAS 2 can be rendered.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -23,7 +25,9 @@ def test_oas2_minimal(testrenderer, oas_fragment): responses: '200': description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -35,7 +39,9 @@ def test_oas2_minimal(testrenderer, oas_fragment): def test_oas2_complete(testrenderer, oas_fragment): """Feature rich OAS 2 can be rendered.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -79,7 +85,9 @@ def test_oas2_complete(testrenderer, oas_fragment): description: a response description '404': description: a username not found - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -110,7 +118,9 @@ def test_oas2_complete(testrenderer, oas_fragment): def test_oas2_schema_example(testrenderer, oas_fragment): """Schema's 'example' property can be used in example snippets.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -134,7 +144,9 @@ def test_oas2_schema_example(testrenderer, oas_fragment): type: integer type: array description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -162,7 +174,9 @@ def test_oas2_complete_generate_examples_from_schema(fakestate, oas_fragment): testrenderer = renderers.HttpdomainRenderer( fakestate, {"generate-examples-from-schemas": True} ) - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" swagger: "2.0" info: title: An example spec @@ -181,7 +195,9 @@ def test_oas2_complete_generate_examples_from_schema(fakestate, oas_fragment): type: integer type: array description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -206,7 +222,9 @@ def test_oas2_complete_generate_examples_from_schema(fakestate, oas_fragment): def test_oas3_minimal(testrenderer, oas_fragment): """Minimal OAS 3 can be rendered.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" openapi: 3.0.3 info: title: An example spec @@ -217,7 +235,9 @@ def test_oas3_minimal(testrenderer, oas_fragment): responses: '200': description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -229,7 +249,9 @@ def test_oas3_minimal(testrenderer, oas_fragment): def test_oas3_complete(testrenderer, oas_fragment): """Feature rich OAS 3 can be rendered.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" openapi: 3.0.3 info: title: An example spec @@ -276,7 +298,9 @@ def test_oas3_complete(testrenderer, oas_fragment): description: a response description '404': description: a username not found - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -307,7 +331,9 @@ def test_oas3_complete(testrenderer, oas_fragment): def test_oas3_schema_example(testrenderer, oas_fragment): """Schema's 'example' property can be used in example snippets.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" openapi: 3.0.3 info: title: An example spec @@ -331,7 +357,9 @@ def test_oas3_schema_example(testrenderer, oas_fragment): type: integer type: array description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -359,7 +387,9 @@ def test_oas3_generate_examples_from_schema(fakestate, oas_fragment): testrenderer = renderers.HttpdomainRenderer( fakestate, {"generate-examples-from-schemas": True} ) - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" openapi: 3.0.3 info: title: An example spec @@ -378,7 +408,9 @@ def test_oas3_generate_examples_from_schema(fakestate, oas_fragment): type: integer type: array description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -403,7 +435,9 @@ def test_oas3_generate_examples_from_schema(fakestate, oas_fragment): def test_oas3_request_body(testrenderer, oas_fragment): """Request body example is rendered.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" openapi: 3.0.3 info: title: An example spec @@ -423,7 +457,9 @@ def test_oas3_request_body(testrenderer, oas_fragment): responses: '200': description: a response description - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test @@ -447,7 +483,9 @@ def test_oas3_request_body(testrenderer, oas_fragment): def test_oas3_response_example_2xx(testrenderer, oas_fragment): """Response examples are rendered for 2XX status codes.""" - markup = textify(testrenderer.render_restructuredtext_markup(oas_fragment(""" + markup = textify( + testrenderer.render_restructuredtext_markup( + oas_fragment(""" openapi: 3.0.3 info: title: An example spec @@ -474,7 +512,9 @@ def test_oas3_response_example_2xx(testrenderer, oas_fragment): "message": "an error message" } description: resource not found - """))) + """) + ) + ) assert markup == textwrap.dedent("""\ .. http:get:: /test diff --git a/tests/test_openapi.py b/tests/test_openapi.py index d254572..17d3965 100644 --- a/tests/test_openapi.py +++ b/tests/test_openapi.py @@ -1,12 +1,13 @@ """ - tests.test_openapi - ------------------ +tests.test_openapi +------------------ - Tests some stuff of ``sphinxcontrib.openapi`` module. +Tests some stuff of ``sphinxcontrib.openapi`` module. - :copyright: (c) 2016, Ihor Kalnytskyi. - :license: BSD, see LICENSE for details. +:copyright: (c) 2016, Ihor Kalnytskyi. +:license: BSD, see LICENSE for details. """ + import json import os import textwrap @@ -21,43 +22,42 @@ from sphinxcontrib.openapi import utils -class TestOpenApi2HttpDomain(object): - +class TestOpenApi2HttpDomain: def test_basic(self): renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'paths': { - '/resources/{kind}': { - 'get': { - 'summary': 'List Resources', - 'description': '~ some useful description ~', - 'parameters': [ + spec = { + "paths": { + "/resources/{kind}": { + "get": { + "summary": "List Resources", + "description": "~ some useful description ~", + "parameters": [ { - 'name': 'kind', - 'in': 'path', - 'type': 'string', - 'description': 'Kind of resource to list.', + "name": "kind", + "in": "path", + "type": "string", + "description": "Kind of resource to list.", }, { - 'name': 'limit', - 'in': 'query', - 'type': 'integer', - 'description': 'Show up to `limit` entries.', + "name": "limit", + "in": "query", + "type": "integer", + "description": "Show up to `limit` entries.", }, { - 'name': 'If-None-Match', - 'in': 'header', - 'type': 'string', - 'description': 'Last known resource ETag.' + "name": "If-None-Match", + "in": "header", + "type": "string", + "description": "Last known resource ETag.", }, ], - 'responses': { - '200': { - 'description': 'An array of resources.', - 'headers': { - 'ETag': { - 'description': 'Resource ETag.', - 'type': 'string' + "responses": { + "200": { + "description": "An array of resources.", + "headers": { + "ETag": { + "description": "Resource ETag.", + "type": "string", }, }, }, @@ -65,9 +65,13 @@ def test_basic(self): }, }, }, - })) + } + + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources/{kind} :synopsis: List Resources @@ -85,106 +89,105 @@ def test_basic(self): Last known resource ETag. :resheader ETag: Resource ETag. - ''').lstrip() + """).lstrip() + ) def test_groups(self): - renderer = renderers.HttpdomainOldRenderer(None, {'group': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'tags': [ - {'name': 'tags'}, - {'name': 'pets'}, + renderer = renderers.HttpdomainOldRenderer(None, {"group": True}) + spec = { + "tags": [ + {"name": "tags"}, + {"name": "pets"}, ], - 'paths': collections.OrderedDict([ - ('/', { - 'get': { - 'summary': 'Index', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'Index', - 'content': { - 'application/json': { - 'pets': 'https://example.com/api/pets', - 'tags': 'https://example.com/api/tags', + "paths": { + "/": { + "get": { + "summary": "Index", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "Index", + "content": { + "application/json": { + "pets": "https://example.com/api/pets", + "tags": "https://example.com/api/tags", } - } + }, }, }, }, - }), - ('/pets', { - 'get': { - 'summary': 'List Pets', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'Pets', - 'content': { - 'application/json': [ - { - 'example': '{"foo": "bar"}' - }, + }, + "/pets": { + "get": { + "summary": "List Pets", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "Pets", + "content": { + "application/json": [ + {"example": '{"foo": "bar"}'}, ], }, }, }, - 'tags': [ - 'pets', + "tags": [ + "pets", ], }, - }), - ('/pets/{name}', { - 'get': { - 'summary': 'Show Pet', - 'description': '~ some useful description ~', - 'parameters': [ + }, + "/pets/{name}": { + "get": { + "summary": "Show Pet", + "description": "~ some useful description ~", + "parameters": [ { - 'name': 'name', - 'in': 'path', - 'type': 'string', - 'description': 'Name of pet.', + "name": "name", + "in": "path", + "type": "string", + "description": "Name of pet.", }, ], - 'responses': { - '200': { - 'description': 'A Pet', - 'content': { - 'application/json': { - 'example': '{"foo": "bar"}' - } - } + "responses": { + "200": { + "description": "A Pet", + "content": { + "application/json": {"example": '{"foo": "bar"}'} + }, }, }, - 'tags': [ - 'pets', + "tags": [ + "pets", ], }, - }), - ('/tags', { - 'get': { - 'summary': 'List Tags', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'Tags', - 'content': { - 'application/json': [ - { - 'example': '{"foo": "bar"}' - }, + }, + "/tags": { + "get": { + "summary": "List Tags", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "Tags", + "content": { + "application/json": [ + {"example": '{"foo": "bar"}'}, ], - } + }, }, }, - 'tags': [ - 'tags', - 'pets', + "tags": [ + "tags", + "pets", ], }, - }), - ]), - })) - assert text == textwrap.dedent(''' + }, + }, + } + + text = "\n".join(renderer.render_restructuredtext_markup(spec)) + assert ( + text + == textwrap.dedent(""" tags ==== @@ -235,30 +238,33 @@ def test_groups(self): :status 200: Index - ''').lstrip() + """).lstrip() + ) def test_two_resources(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, } } - spec['paths']['/resource_b'] = { - 'post': { - 'description': 'resource b', - 'responses': { - '404': {'description': 'error'}, - } + spec["paths"]["/resource_b"] = { + "post": { + "description": "resource b", + "responses": { + "404": {"description": "error"}, + }, } } renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + text = "\n".join(renderer.render_restructuredtext_markup(spec)) + assert ( + text + == textwrap.dedent(""" .. http:get:: /resource_a :synopsis: null @@ -274,32 +280,40 @@ def test_two_resources(self): :status 404: error - ''').lstrip() + """).lstrip() + ) def test_path_option(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, } } - spec['paths']['/resource_b'] = { - 'post': { - 'description': 'resource b', - 'responses': { - '404': {'description': 'error'}, - } + spec["paths"]["/resource_b"] = { + "post": { + "description": "resource b", + "responses": { + "404": {"description": "error"}, + }, } } - renderer = renderers.HttpdomainOldRenderer(None, {'paths': [ - '/resource_a', - ]}) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + renderer = renderers.HttpdomainOldRenderer( + None, + { + "paths": [ + "/resource_a", + ] + }, + ) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) + assert ( + text + == textwrap.dedent(""" .. http:get:: /resource_a :synopsis: null @@ -307,32 +321,40 @@ def test_path_option(self): :status 200: ok - ''').lstrip() + """).lstrip() + ) def test_include_option(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, } } - spec['paths']['/resource_b'] = { - 'post': { - 'description': 'resource b', - 'responses': { - '404': {'description': 'error'}, - } + spec["paths"]["/resource_b"] = { + "post": { + "description": "resource b", + "responses": { + "404": {"description": "error"}, + }, } } - renderer = renderers.HttpdomainOldRenderer(None, {'include': [ - '/resource', - ]}) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + renderer = renderers.HttpdomainOldRenderer( + None, + { + "include": [ + "/resource", + ] + }, + ) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) + assert ( + text + == textwrap.dedent(""" .. http:get:: /resource_a :synopsis: null @@ -348,32 +370,40 @@ def test_include_option(self): :status 404: error - ''').lstrip() + """).lstrip() + ) def test_exclude_option(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, } } - spec['paths']['/resource_b'] = { - 'post': { - 'description': 'resource b', - 'responses': { - '404': {'description': 'error'}, - } + spec["paths"]["/resource_b"] = { + "post": { + "description": "resource b", + "responses": { + "404": {"description": "error"}, + }, } } - renderer = renderers.HttpdomainOldRenderer(None, {'exclude': [ - '/.*_a', - ]}) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + renderer = renderers.HttpdomainOldRenderer( + None, + { + "exclude": [ + "/.*_a", + ] + }, + ) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) + assert ( + text + == textwrap.dedent(""" .. http:post:: /resource_b :synopsis: null @@ -381,41 +411,44 @@ def test_exclude_option(self): :status 404: error - ''').lstrip() + """).lstrip() + ) def test_method_option(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, }, - 'post': { - 'description': 'resource a', - 'responses': { - '201': {'description': 'ok'}, - } + "post": { + "description": "resource a", + "responses": { + "201": {"description": "ok"}, + }, + }, + "put": { + "description": "resource a", + "responses": { + "404": {"description": "error"}, + }, }, - 'put': { - 'description': 'resource a', - 'responses': { - '404': {'description': 'error'}, - } - } } renderer = renderers.HttpdomainOldRenderer( None, { - 'methods': ['post'], - 'paths': ['/resource_a'], + "methods": ["post"], + "paths": ["/resource_a"], }, ) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:post:: /resource_a :synopsis: null @@ -423,43 +456,46 @@ def test_method_option(self): :status 201: ok - ''').lstrip() + """).lstrip() + ) def test_root_parameters(self): - spec = {'paths': {}} - spec['paths']['/resources/{name}'] = collections.OrderedDict() + spec = {"paths": {}} + spec["paths"]["/resources/{name}"] = {} - spec['paths']['/resources/{name}']['parameters'] = [ + spec["paths"]["/resources/{name}"]["parameters"] = [ { - 'name': 'name', - 'in': 'path', - 'type': 'string', - 'description': 'The name of the resource.', + "name": "name", + "in": "path", + "type": "string", + "description": "The name of the resource.", } ] - spec['paths']['/resources/{name}']['get'] = { - 'summary': 'Fetch a Resource', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'The fetched resource.', + spec["paths"]["/resources/{name}"]["get"] = { + "summary": "Fetch a Resource", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "The fetched resource.", }, }, } - spec['paths']['/resources/{name}']['put'] = { - 'summary': 'Modify a Resource', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'The modified resource.', + spec["paths"]["/resources/{name}"]["put"] = { + "summary": "Modify a Resource", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "The modified resource.", }, }, } renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources/{name} :synopsis: Fetch a Resource @@ -483,58 +519,63 @@ def test_root_parameters(self): The name of the resource. :status 200: The modified resource. - ''').lstrip() + """).lstrip() + ) def test_path_invalid(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, } } - spec['paths']['/resource_b'] = { - 'post': { - 'description': 'resource b', - 'responses': { - '404': {'description': 'error'}, - } + spec["paths"]["/resource_b"] = { + "post": { + "description": "resource b", + "responses": { + "404": {"description": "error"}, + }, } } - renderer = renderers.HttpdomainOldRenderer(None, {'paths': [ - '/resource_a', - '/resource_invalid_name', - ]}) + renderer = renderers.HttpdomainOldRenderer( + None, + { + "paths": [ + "/resource_a", + "/resource_invalid_name", + ] + }, + ) with pytest.raises(ValueError) as exc: - '\n'.join(renderer.render_restructuredtext_markup(spec)) + "\n".join(renderer.render_restructuredtext_markup(spec)) assert str(exc.value) == ( - 'One or more paths are not defined in the spec: ' - '/resource_invalid_name.' + "One or more paths are not defined in the spec: /resource_invalid_name." ) def test_unicode_is_allowed(self): spec = { - 'paths': { - '/resource_a': { - 'get': { - 'description': '\u041f', - 'responses': { - '200': {'description': 'ok'} - } + "paths": { + "/resource_a": { + "get": { + "description": "\u041f", + "responses": {"200": {"description": "ok"}}, } } } } renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resource_a :synopsis: null @@ -542,97 +583,89 @@ def test_unicode_is_allowed(self): :status 200: ok - ''').lstrip() + """).lstrip() + ) def test_json_in_out(self): renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'definitions': { - 'CreateResourceSchema': { - 'additionalProperties': False, - 'properties': { - 'string_field': { - 'type': 'string', - 'description': 'some input string' - }, - 'int_field': { - 'default': 1, - 'type': 'integer', - }, - }, - 'required': [ - 'string_field' - ], - 'title': 'CreateResourceSchema', - 'type': 'object' - }, - 'ResourceSchema': { - 'properties': { - 'string_field': { - 'type': 'string', - 'description': 'some output string' + text = "\n".join( + renderer.render_restructuredtext_markup( + { + "definitions": { + "CreateResourceSchema": { + "additionalProperties": False, + "properties": { + "string_field": { + "type": "string", + "description": "some input string", + }, + "int_field": { + "default": 1, + "type": "integer", + }, + }, + "required": ["string_field"], + "title": "CreateResourceSchema", + "type": "object", }, - 'int_field': { - 'type': 'integer', + "ResourceSchema": { + "properties": { + "string_field": { + "type": "string", + "description": "some output string", + }, + "int_field": { + "type": "integer", + }, + }, + "required": ["string_field"], + "title": "ResourceSchema", + "type": "object", }, - }, - 'required': [ - 'string_field' - ], - 'title': 'ResourceSchema', - 'type': 'object' - }, - 'Error': { - 'properties': { - 'errors': { - 'type': 'object' + "Error": { + "properties": { + "errors": {"type": "object"}, + "message": {"type": "string"}, + }, + "required": ["message"], + "title": "Error", + "type": "object", }, - 'message': { - 'type': 'string' - } }, - 'required': [ - 'message' - ], - 'title': 'Error', - 'type': 'object' - }, - }, - 'paths': { - '/resources': { - 'post': { - 'description': '~ some useful description ~', - 'parameters': [ - { - 'in': 'body', - 'name': 'CreateResourceSchema', - 'required': True, - 'schema': { - '$ref': - '#/definitions/CreateResourceSchema' - } - }, - ], - 'responses': { - '201': { - 'description': '~ some useful description ~', - 'schema': { - '$ref': '#/definitions/ResourceSchema' - } + "paths": { + "/resources": { + "post": { + "description": "~ some useful description ~", + "parameters": [ + { + "in": "body", + "name": "CreateResourceSchema", + "required": True, + "schema": { + "$ref": "#/definitions/CreateResourceSchema" + }, + }, + ], + "responses": { + "201": { + "description": "~ some useful description ~", + "schema": { + "$ref": "#/definitions/ResourceSchema" + }, + }, + "default": { + "description": "~ some useful description ~", + "schema": {"$ref": "#/definitions/Error"}, + }, + }, }, - 'default': { - 'description': '~ some useful description ~', - 'schema': { - '$ref': '#/definitions/Error' - } - } }, }, - }, - }, - })) + } + ) + ) - text2 = textwrap.dedent(''' + text2 = textwrap.dedent(""" .. http:post:: /resources :synopsis: null @@ -650,63 +683,68 @@ def test_json_in_out(self): :>json integer int_field: :>json string string_field: some output string (required) - ''').lstrip() + """).lstrip() assert text == text2 -class TestOpenApi3HttpDomain(object): - +class TestOpenApi3HttpDomain: def test_basic(self): renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/resources/{kind}': { - 'get': { - 'summary': 'List Resources', - 'description': '~ some useful description ~', - 'parameters': [ - { - 'name': 'kind', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Kind of resource to list.', - }, - { - 'name': 'limit', - 'in': 'query', - 'schema': {'type': 'integer'}, - 'description': 'Show up to `limit` entries.', - }, - { - 'name': 'If-None-Match', - 'in': 'header', - 'schema': {'type': 'string'}, - 'description': 'Last known resource ETag.' - }, - ], - 'requestBody': { - 'content': { - 'application/json': { - 'example': '{"foo2": "bar2"}' - } - } - }, - 'responses': { - '200': { - 'description': 'An array of resources.', - 'content': { - 'application/json': { - 'example': '{"foo": "bar"}' + text = "\n".join( + renderer.render_restructuredtext_markup( + { + "openapi": "3.0.0", + "paths": { + "/resources/{kind}": { + "get": { + "summary": "List Resources", + "description": "~ some useful description ~", + "parameters": [ + { + "name": "kind", + "in": "path", + "schema": {"type": "string"}, + "description": "Kind of resource to list.", + }, + { + "name": "limit", + "in": "query", + "schema": {"type": "integer"}, + "description": "Show up to `limit` entries.", + }, + { + "name": "If-None-Match", + "in": "header", + "schema": {"type": "string"}, + "description": "Last known resource ETag.", + }, + ], + "requestBody": { + "content": { + "application/json": { + "example": '{"foo2": "bar2"}' + } } - } + }, + "responses": { + "200": { + "description": "An array of resources.", + "content": { + "application/json": { + "example": '{"foo": "bar"}' + } + }, + }, + }, }, }, }, - }, - }, - })) - assert text == textwrap.dedent(''' + } + ) + ) + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources/{kind} :synopsis: List Resources @@ -722,46 +760,52 @@ def test_basic(self): An array of resources. :reqheader If-None-Match: Last known resource ETag. - ''').lstrip() + """).lstrip() + ) def test_rfc7807(self): - # Fix order to have a reliable test - pb_example = collections.OrderedDict() + pb_example = {} pb_example["type"] = "string" pb_example["title"] = "string" pb_example["status"] = 1 pb_example["detail"] = "string" pb_example["instance"] = "string" - renderer = renderers.HttpdomainOldRenderer(None, {'examples': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/problem': { - 'post': { - 'summary': 'Problem', - 'description': '~ some useful description ~', - 'requestBody': { - 'content': { - 'application/problem+json': { - 'example': pb_example - } - } - }, - 'responses': { - '200': { - 'description': 'An array of resources.', - 'content': { - 'application/json': { - 'example': '{"foo": "bar"}' + renderer = renderers.HttpdomainOldRenderer(None, {"examples": True}) + text = "\n".join( + renderer.render_restructuredtext_markup( + { + "openapi": "3.0.0", + "paths": { + "/problem": { + "post": { + "summary": "Problem", + "description": "~ some useful description ~", + "requestBody": { + "content": { + "application/problem+json": { + "example": pb_example + } } - } + }, + "responses": { + "200": { + "description": "An array of resources.", + "content": { + "application/json": { + "example": '{"foo": "bar"}' + } + }, + }, + }, }, }, }, - }, - }, - })) - assert text == textwrap.dedent(''' + } + ) + ) + assert ( + text + == textwrap.dedent(""" .. http:post:: /problem :synopsis: Problem @@ -798,107 +842,110 @@ def test_rfc7807(self): {"foo": "bar"} - ''').lstrip() + """).lstrip() + ) def test_groups(self): - renderer = renderers.HttpdomainOldRenderer(None, {'group': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'tags': [ - {'name': 'tags'}, - {'name': 'pets'}, - ], - 'paths': collections.OrderedDict([ - ('/', { - 'get': { - 'summary': 'Index', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'Index', - 'content': { - 'application/json': { - 'pets': 'https://example.com/api/pets', - 'tags': 'https://example.com/api/tags', - } - } + renderer = renderers.HttpdomainOldRenderer(None, {"group": True}) + text = "\n".join( + renderer.render_restructuredtext_markup( + { + "openapi": "3.0.0", + "tags": [ + {"name": "tags"}, + {"name": "pets"}, + ], + "paths": { + "/": { + "get": { + "summary": "Index", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "Index", + "content": { + "application/json": { + "pets": "https://example.com/api/pets", + "tags": "https://example.com/api/tags", + } + }, + }, + }, }, }, - }, - }), - ('/pets', { - 'get': { - 'summary': 'List Pets', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'Pets', - 'content': { - 'application/json': [ - { - 'example': '{"foo": "bar"}' + "/pets": { + "get": { + "summary": "List Pets", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "Pets", + "content": { + "application/json": [ + {"example": '{"foo": "bar"}'}, + ], }, - ], + }, }, + "tags": [ + "pets", + ], }, }, - 'tags': [ - 'pets', - ], - }, - }), - ('/pets/{name}', { - 'get': { - 'summary': 'Show Pet', - 'description': '~ some useful description ~', - 'parameters': [ - { - 'name': 'name', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Name of pet.', - }, - ], - 'responses': { - '200': { - 'description': 'A Pet', - 'content': { - 'application/json': { - 'example': '{"foo": "bar"}' - } - } + "/pets/{name}": { + "get": { + "summary": "Show Pet", + "description": "~ some useful description ~", + "parameters": [ + { + "name": "name", + "in": "path", + "schema": {"type": "string"}, + "description": "Name of pet.", + }, + ], + "responses": { + "200": { + "description": "A Pet", + "content": { + "application/json": { + "example": '{"foo": "bar"}' + } + }, + }, + }, + "tags": [ + "pets", + ], }, }, - 'tags': [ - 'pets', - ], - }, - }), - ('/tags', { - 'get': { - 'summary': 'List Tags', - 'description': '~ some useful description ~', - 'responses': { - '200': { - 'description': 'Tags', - 'content': { - 'application/json': [ - { - 'example': '{"foo": "bar"}' + "/tags": { + "get": { + "summary": "List Tags", + "description": "~ some useful description ~", + "responses": { + "200": { + "description": "Tags", + "content": { + "application/json": [ + {"example": '{"foo": "bar"}'}, + ], }, - ], - } + }, + }, + "tags": [ + "tags", + "pets", + ], }, }, - 'tags': [ - 'tags', - 'pets', - ], }, - }), - ]), - })) - assert text == textwrap.dedent(''' + } + ) + ) + assert ( + text + == textwrap.dedent(""" tags ==== @@ -949,61 +996,68 @@ def test_groups(self): :status 200: Index - ''').lstrip() + """).lstrip() + ) def test_required_parameters(self): renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/resources/{kind}': { - 'get': { - 'summary': 'List Resources', - 'description': '~ some useful description ~', - 'parameters': [ - { - 'name': 'kind', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Kind of resource to list.', - }, - { - 'name': 'limit', - 'in': 'query', - 'required': True, - 'schema': {'type': 'integer'}, - 'description': 'Show up to `limit` entries.', - }, - { - 'name': 'If-None-Match', - 'in': 'header', - 'required': True, - 'schema': {'type': 'string'}, - 'description': 'Last known resource ETag.' - }, - ], - 'requestBody': { - 'content': { - 'application/json': { - 'example': '{"foo2": "bar2"}' - } - } - }, - 'responses': { - '200': { - 'description': 'An array of resources.', - 'content': { - 'application/json': { - 'example': '{"foo": "bar"}' + text = "\n".join( + renderer.render_restructuredtext_markup( + { + "openapi": "3.0.0", + "paths": { + "/resources/{kind}": { + "get": { + "summary": "List Resources", + "description": "~ some useful description ~", + "parameters": [ + { + "name": "kind", + "in": "path", + "schema": {"type": "string"}, + "description": "Kind of resource to list.", + }, + { + "name": "limit", + "in": "query", + "required": True, + "schema": {"type": "integer"}, + "description": "Show up to `limit` entries.", + }, + { + "name": "If-None-Match", + "in": "header", + "required": True, + "schema": {"type": "string"}, + "description": "Last known resource ETag.", + }, + ], + "requestBody": { + "content": { + "application/json": { + "example": '{"foo2": "bar2"}' + } } - } + }, + "responses": { + "200": { + "description": "An array of resources.", + "content": { + "application/json": { + "example": '{"foo": "bar"}' + } + }, + }, + }, }, }, }, - }, - }, - })) - assert text == textwrap.dedent(''' + } + ) + ) + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources/{kind} :synopsis: List Resources @@ -1021,167 +1075,174 @@ def test_required_parameters(self): :reqheader If-None-Match: Last known resource ETag. (Required) - ''').lstrip() + """).lstrip() + ) def test_example_generation(self): - renderer = renderers.HttpdomainOldRenderer(None, {'examples': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': collections.OrderedDict([ - ('/resources/', collections.OrderedDict([ - ('get', { - 'summary': 'List Resources', - 'description': '~ some useful description ~', - 'parameters': [ - { - 'name': 'kind', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Kind of resource to list.', - }, - { - 'name': 'limit', - 'in': 'query', - 'required': True, - 'schema': {'type': 'integer'}, - 'description': 'Show up to `limit` entries.', - }, - { - 'name': 'If-None-Match', - 'in': 'header', - 'schema': {'type': 'string'}, - 'description': 'Last known resource ETag.' + renderer = renderers.HttpdomainOldRenderer(None, {"examples": True}) + text = "\n".join( + renderer.render_restructuredtext_markup( + { + "openapi": "3.0.0", + "paths": { + "/resources/": { + "get": { + "summary": "List Resources", + "description": "~ some useful description ~", + "parameters": [ + { + "name": "kind", + "in": "path", + "schema": {"type": "string"}, + "description": "Kind of resource to list.", + }, + { + "name": "limit", + "in": "query", + "required": True, + "schema": {"type": "integer"}, + "description": "Show up to `limit` entries.", + }, + { + "name": "If-None-Match", + "in": "header", + "schema": {"type": "string"}, + "description": "Last known resource ETag.", + }, + ], + "responses": { + "200": { + "description": "An array of resources.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Resource", # noqa + }, + }, + } + }, + }, + }, }, - ], - 'responses': { - '200': { - 'description': 'An array of resources.', - 'content': { - 'application/json': { - 'schema': { - 'type': 'array', - 'items': { - '$ref': '#/components/schemas/Resource', # noqa + "post": { + "summary": "Create Resource", + "description": "~ some useful description ~", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Resource", }, - }, + } } - } + }, + "responses": { + "200": { + "description": "The created resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Resource", # noqa + }, + } + }, + }, + }, }, }, - }), - ('post', { - 'summary': 'Create Resource', - 'description': '~ some useful description ~', - 'parameters': [], - 'requestBody': { - 'content': { - 'application/json': { - 'schema': { - '$ref': '#/components/schemas/Resource', # noqa + "/resources/{kind}": { + "get": { + "summary": "Show Resource", + "description": "~ some useful description ~", + "parameters": [ + { + "name": "kind", + "in": "path", + "schema": {"type": "string"}, + "description": "Kind of resource to list.", }, - } - } - }, - 'responses': { - '200': { - 'description': 'The created resource.', - 'content': { - 'application/json': { - 'schema': { - '$ref': '#/components/schemas/Resource', # noqa + ], + "responses": { + "200": { + "description": "The created resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Resource", # noqa + }, + } }, - } - } - }, - }, - }), - ])), - ('/resources/{kind}', collections.OrderedDict([ - ('get', { - 'summary': 'Show Resource', - 'description': '~ some useful description ~', - 'parameters': [ - { - 'name': 'kind', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Kind of resource to list.', + }, + }, }, - ], - 'responses': { - '200': { - 'description': 'The created resource.', - 'content': { - 'application/json': { - 'schema': { - '$ref': '#/components/schemas/Resource', # noqa - }, + "patch": { + "summary": "Update Resource (partial)", + "description": "~ some useful description ~", + "parameters": [ + { + "name": "kind", + "in": "path", + "schema": {"type": "string"}, + "description": "Kind of resource to list.", + }, + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Resource", + }, + } } - } + }, + "responses": { + "200": { + "description": "The created resource.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Resource", # noqa + }, + } + }, + }, + }, }, }, - }), - ('patch', { - 'summary': 'Update Resource (partial)', - 'description': '~ some useful description ~', - 'parameters': [ - { - 'name': 'kind', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Kind of resource to list.', - }, - ], - 'requestBody': { - 'content': { - 'application/json': { - 'schema': { - '$ref': '#/components/schemas/Resource', # noqa + }, + "components": { + "schemas": { + "Resource": { + "type": "object", + "properties": { + "kind": { + "title": "Kind", + "type": "string", + "readOnly": True, }, - } - } - }, - 'responses': { - '200': { - 'description': 'The created resource.', - 'content': { - 'application/json': { - 'schema': { - '$ref': '#/components/schemas/Resource', # noqa - }, - } - } + "description": { + "title": "Description", + "type": "string", + }, + "data": { + "title": "Data", + "type": "string", + "format": "byte", + }, + }, }, }, - }), - ])), - ]), - 'components': { - 'schemas': { - 'Resource': { - 'type': 'object', - 'properties': collections.OrderedDict([ - ('kind', { - 'title': 'Kind', - 'type': 'string', - 'readOnly': True, - }), - ('description', { - 'title': 'Description', - 'type': 'string', - }), - ('data', { - 'title': 'Data', - 'type': 'string', - 'format': 'byte', - }), - ]), }, - }, - }, - })) + } + ) + ) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources/ :synopsis: List Resources @@ -1334,64 +1395,65 @@ def test_example_generation(self): "data": "c3RyaW5n" } - ''').lstrip() + """).lstrip() + ) def test_get_example_with_explode(self): - renderer = renderers.HttpdomainOldRenderer(None, {'examples': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': collections.OrderedDict([ - ('/resources/', collections.OrderedDict([ - ('get', { - 'summary': 'List Resources', - 'description': '~ some useful description ~', - 'parameters': [ + renderer = renderers.HttpdomainOldRenderer(None, {"examples": True}) + spec = { + "openapi": "3.0.0", + "paths": { + "/resources/": { + "get": { + "summary": "List Resources", + "description": "~ some useful description ~", + "parameters": [ { - 'name': 'params', - 'in': 'query', - 'required': True, - 'schema': { - 'type': 'array', - 'items': { - 'type': 'string' - } + "name": "params", + "in": "query", + "required": True, + "schema": { + "type": "array", + "items": {"type": "string"}, }, - 'style': 'form', - 'explode': True, - 'example': [ - 'p1', - 'p2', + "style": "form", + "explode": True, + "example": [ + "p1", + "p2", ], - 'description': 'List with explode set to True' + "description": "List with explode set to True", }, { - 'name': 'values', - 'in': 'query', - 'required': True, - 'schema': { - 'type': 'object', - 'additionalProperties': True + "name": "values", + "in": "query", + "required": True, + "schema": { + "type": "object", + "additionalProperties": True, + }, + "style": "form", + "explode": True, + "example": { + "v1": "V1", + "v2": "V2", }, - 'style': 'form', - 'explode': True, - 'example': collections.OrderedDict([ - ('v1', 'V1'), - ('v2', 'V2'), - ]), - 'description': 'Dict with explode set to True' + "description": "Dict with explode set to True", }, ], - 'responses': { - '200': { - 'description': 'OK' - }, + "responses": { + "200": {"description": "OK"}, }, - }), - ])), - ]), - })) + }, + }, + }, + } + + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources/ :synopsis: List Resources @@ -1415,95 +1477,89 @@ def test_get_example_with_explode(self): :status 200: OK - ''').lstrip() + """).lstrip() + ) def test_callback(self): renderer = renderers.HttpdomainOldRenderer(None, {}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/resources/{kind}': { - 'post': { - 'summary': 'List Resources', - 'description': '~ some useful description ~', - 'parameters': [ + spec = { + "openapi": "3.0.0", + "paths": { + "/resources/{kind}": { + "post": { + "summary": "List Resources", + "description": "~ some useful description ~", + "parameters": [ { - 'name': 'kind', - 'in': 'path', - 'schema': {'type': 'string'}, - 'description': 'Kind of resource to list.', + "name": "kind", + "in": "path", + "schema": {"type": "string"}, + "description": "Kind of resource to list.", }, { - 'name': 'callback', - 'in': 'query', - 'description': 'the callback address', - 'required': False, - 'schema': { - 'type': 'string', - 'format': 'uri' - }, - 'example': 'http://client.com/callback' - } + "name": "callback", + "in": "query", + "description": "the callback address", + "required": False, + "schema": {"type": "string", "format": "uri"}, + "example": "http://client.com/callback", + }, ], - 'requestBody': { - 'content': { - 'application/json': { - 'example': '{"foo2": "bar2"}' - } + "requestBody": { + "content": { + "application/json": {"example": '{"foo2": "bar2"}'} } }, - 'responses': { - '202': { - 'description': 'Something', - 'content': { - 'application/json': { - 'example': '{"foo": "bar"}' - } - } + "responses": { + "202": { + "description": "Something", + "content": { + "application/json": {"example": '{"foo": "bar"}'} + }, }, }, - 'callbacks': { - 'callback': { - '${request.query.callback}': { - 'post': { - 'summary': 'Response callback', - 'operationId': 'sampleCB', - 'requestBody': { - 'required': True, - 'description': 'Result', - 'content': { - 'application/json': { - 'schema': { - 'type': 'object', - 'required': ['status'], - 'properties': { - 'status': { - 'type': - 'string', - 'enum': [ - 'OK', - 'ERROR' - ] + "callbacks": { + "callback": { + "${request.query.callback}": { + "post": { + "summary": "Response callback", + "operationId": "sampleCB", + "requestBody": { + "required": True, + "description": "Result", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["status"], + "properties": { + "status": { + "type": "string", + "enum": [ + "OK", + "ERROR", + ], } - } + }, } } - } + }, + }, + "responses": { + "200": {"description": "Success"} }, - 'responses': { - '200': { - 'description': 'Success' - } - } } } } - } + }, }, }, }, - })) - assert text == textwrap.dedent(''' + } + text = "\n".join(renderer.render_restructuredtext_markup(spec)) + assert ( + text + == textwrap.dedent(""" .. http:post:: /resources/{kind} :synopsis: List Resources @@ -1528,35 +1584,40 @@ def test_callback(self): :status 200: Success - ''').lstrip() + """).lstrip() + ) def test_string_example(self): - renderer = renderers.HttpdomainOldRenderer(None, {'examples': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/resources': { - 'get': { - 'summary': 'Get resources', - 'responses': { - '200': { - 'description': 'Something', - 'content': { - 'application/json': { - 'schema': { - 'type': 'string', - 'example': '"A sample"', + renderer = renderers.HttpdomainOldRenderer(None, {"examples": True}) + spec = { + "openapi": "3.0.0", + "paths": { + "/resources": { + "get": { + "summary": "Get resources", + "responses": { + "200": { + "description": "Something", + "content": { + "application/json": { + "schema": { + "type": "string", + "example": '"A sample"', } } - } + }, }, }, }, }, }, - })) + } + + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources :synopsis: Get resources @@ -1582,46 +1643,49 @@ def test_string_example(self): "A sample" - ''').lstrip() + """).lstrip() + ) def test_ref_example(self): - renderer = renderers.HttpdomainOldRenderer(None, {'examples': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/resources': { - 'get': { - 'summary': 'Get resources', - 'responses': { - '200': { - 'description': 'Something', - 'content': { - 'application/json': { - 'schema': { - '$ref': - '#/components/schemas/Data', + renderer = renderers.HttpdomainOldRenderer(None, {"examples": True}) + spec = { + "openapi": "3.0.0", + "paths": { + "/resources": { + "get": { + "summary": "Get resources", + "responses": { + "200": { + "description": "Something", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Data", } } - } + }, }, }, }, }, }, - 'components': { - 'schemas': { - 'Data': { - 'type': 'object', - 'additionalProperties': True, - 'example': { - 'prop1': "Sample 1", - } + "components": { + "schemas": { + "Data": { + "type": "object", + "additionalProperties": True, + "example": { + "prop1": "Sample 1", + }, } } - } - })) + }, + } + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:get:: /resources :synopsis: Get resources @@ -1649,41 +1713,44 @@ def test_ref_example(self): "prop1": "Sample 1" } - ''').lstrip() + """).lstrip() + ) def test_method_option(self): - spec = collections.defaultdict(collections.OrderedDict) - spec['paths']['/resource_a'] = { - 'get': { - 'description': 'resource a', - 'responses': { - '200': {'description': 'ok'}, - } + spec = collections.defaultdict(dict) + spec["paths"]["/resource_a"] = { + "get": { + "description": "resource a", + "responses": { + "200": {"description": "ok"}, + }, }, - 'post': { - 'description': 'resource a', - 'responses': { - '201': {'description': 'ok'}, - } + "post": { + "description": "resource a", + "responses": { + "201": {"description": "ok"}, + }, + }, + "put": { + "description": "resource a", + "responses": { + "404": {"description": "error"}, + }, }, - 'put': { - 'description': 'resource a', - 'responses': { - '404': {'description': 'error'}, - } - } } renderer = renderers.HttpdomainOldRenderer( None, { - 'methods': ['post'], - 'paths': ['/resource_a'], + "methods": ["post"], + "paths": ["/resource_a"], }, ) - text = '\n'.join(renderer.render_restructuredtext_markup(spec)) + text = "\n".join(renderer.render_restructuredtext_markup(spec)) - assert text == textwrap.dedent(''' + assert ( + text + == textwrap.dedent(""" .. http:post:: /resource_a :synopsis: null @@ -1691,145 +1758,150 @@ def test_method_option(self): :status 201: ok - ''').lstrip() - + """).lstrip() + ) -class TestResolveRefs(object): +class TestResolveRefs: def test_ref_resolving(self): data = { - 'foo': { - 'a': 13, - 'b': { - 'c': True, - } - }, - 'bar': { - '$ref': '#/foo/b' + "foo": { + "a": 13, + "b": { + "c": True, + }, }, - 'baz': [ - {'$ref': '#/foo/a'}, - {'$ref': '#/foo/b'}, - 'batman', - ] + "bar": {"$ref": "#/foo/b"}, + "baz": [ + {"$ref": "#/foo/a"}, + {"$ref": "#/foo/b"}, + "batman", + ], } - assert utils._resolve_refs('', data) == { - 'foo': { - 'a': 13, - 'b': { - 'c': True, - } + assert utils._resolve_refs("", data) == { + "foo": { + "a": 13, + "b": { + "c": True, + }, }, - 'bar': { - 'c': True, + "bar": { + "c": True, }, - 'baz': [ + "baz": [ 13, - {'c': True}, - 'batman', - ] + {"c": True}, + "batman", + ], } def test_relative_ref_resolving_on_fs(self): - baseuri = 'file://%s' % os.path.abspath(__file__) + baseuri = f"file://{os.path.abspath(__file__)}" data = { - 'bar': { - '$ref': 'testdata/foo.json#/foo/b', + "bar": { + "$ref": "testdata/foo.json#/foo/b", }, # check also JSON to YAML references: - 'baz': { - '$ref': 'testdata/foo.yaml#/foo', - } + "baz": { + "$ref": "testdata/foo.yaml#/foo", + }, } # import pdb # pdb.set_trace() assert utils._resolve_refs(baseuri, data) == { - 'bar': { - 'c': True, + "bar": { + "c": True, }, - 'baz': { - 'a': 17, - 'b': 13, + "baz": { + "a": 17, + "b": 13, }, } - @mock.patch('requests.get') + @mock.patch("requests.get") def test_relative_ref_resolving_remote(self, mock_get): baseuri = os.path.abspath(__file__) with open( - os.path.join(os.path.dirname(baseuri), 'testdata', 'foo.json'), - 'r', - encoding='utf-8' + os.path.join(os.path.dirname(baseuri), "testdata", "foo.json"), + encoding="utf-8", ) as file: json_content = json.loads(file.read()) - with open(os.path.join(os.path.dirname(baseuri), 'testdata', 'foo.yaml'), 'rb') as file: + with open( + os.path.join(os.path.dirname(baseuri), "testdata", "foo.yaml"), "rb" + ) as file: yaml_content = file.read() def get_side_effect(path): - if path.endswith('.json'): + if path.endswith(".json"): return mock.Mock(json=mock.Mock(return_value=json_content)) - return mock.Mock(content=yaml_content, read=mock.Mock(side_effect=Exception)) + return mock.Mock( + content=yaml_content, read=mock.Mock(side_effect=Exception) + ) + mock_get.side_effect = get_side_effect data = { - 'bar': { - '$ref': 'testdata/foo.json#/foo/b', + "bar": { + "$ref": "testdata/foo.json#/foo/b", }, # check also JSON to YAML references: - 'baz': { - '$ref': 'testdata/foo.yaml#/foo', - } + "baz": { + "$ref": "testdata/foo.yaml#/foo", + }, } - assert utils._resolve_refs('https://some/remote/file', data) == { - 'bar': { - 'c': True, + assert utils._resolve_refs("https://some/remote/file", data) == { + "bar": { + "c": True, }, - 'baz': { - 'a': 17, - 'b': 13, + "baz": { + "a": 17, + "b": 13, }, } def test_noproperties(self): - renderer = renderers.HttpdomainOldRenderer(None, {'examples': True}) - text = '\n'.join(renderer.render_restructuredtext_markup({ - 'openapi': '3.0.0', - 'paths': { - '/resources': { - 'post': { - 'summary': 'Create Resources', - 'description': '~ some useful description ~', - 'requestBody': { - 'content': { - 'application/json': { - 'schema': { - '$ref': '#/components/schemas/Resource', # noqa + renderer = renderers.HttpdomainOldRenderer(None, {"examples": True}) + data = { + "openapi": "3.0.0", + "paths": { + "/resources": { + "post": { + "summary": "Create Resources", + "description": "~ some useful description ~", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Resource", } } } }, - 'responses': { - '200': { - 'description': 'Something', + "responses": { + "200": { + "description": "Something", }, }, }, }, }, - 'components': { - 'schemas': { - 'Resource': { - 'type': 'object', - 'additionalProperties': True, + "components": { + "schemas": { + "Resource": { + "type": "object", + "additionalProperties": True, }, }, }, + } - })) - assert text == textwrap.dedent(''' + text = "\n".join(renderer.render_restructuredtext_markup(data)) + assert ( + text + == textwrap.dedent(""" .. http:post:: /resources :synopsis: Create Resources @@ -1850,135 +1922,126 @@ def test_noproperties(self): :status 200: Something - ''').lstrip() + """).lstrip() + ) def test_openapi2_examples(tmpdir, run_sphinx): spec = os.path.join( os.path.abspath(os.path.dirname(__file__)), - 'examples', - 'v2.0', - 'json', - 'uber.json') - py.path.local(spec).copy(tmpdir.join('src', 'test-spec.yml')) + "examples", + "v2.0", + "json", + "uber.json", + ) + py.path.local(spec).copy(tmpdir.join("src", "test-spec.yml")) with pytest.raises(ValueError) as excinfo: - run_sphinx('test-spec.yml', options={'examples': True}) + run_sphinx("test-spec.yml", options={"examples": True}) assert str(excinfo.value) == ( - 'Rendering examples is not supported for OpenAPI v2.x specs.') + "Rendering examples is not supported for OpenAPI v2.x specs." + ) -@pytest.mark.parametrize('render_examples', [False, True]) +@pytest.mark.parametrize("render_examples", [False, True]) def test_openapi3_examples(tmpdir, run_sphinx, render_examples): spec = os.path.join( - os.path.abspath(os.path.dirname(__file__)), - 'examples', - 'v3.0', - 'petstore.yaml') - py.path.local(spec).copy(tmpdir.join('src', 'test-spec.yml')) - run_sphinx('test-spec.yml', options={'examples': render_examples}) + os.path.abspath(os.path.dirname(__file__)), "examples", "v3.0", "petstore.yaml" + ) + py.path.local(spec).copy(tmpdir.join("src", "test-spec.yml")) + run_sphinx("test-spec.yml", options={"examples": render_examples}) - rendered_html = tmpdir.join('out', 'index.html').read_text('utf-8') + rendered_html = tmpdir.join("out", "index.html").read_text("utf-8") - assert ('Example response:' in rendered_html) \ - == render_examples + assert ("Example response:" in rendered_html) == render_examples -class TestConvertJsonSchema(object): +class TestConvertJsonSchema: schema = { - 'type': 'object', - 'required': ['name', 'surprise'], - 'properties': { - 'name': { - 'type': 'string', - 'description': 'The name of user'}, - 'alias': { - 'type': 'array', - 'items': { - 'type': 'string'}, - 'description': 'The list of user alias'}, - 'id': { - 'type': 'integer', - 'description': 'the id of user', - 'readOnly': True}, - 'surprise': { - 'type': 'string'}, - 'secret': { - 'type': 'string', - 'readOnly': True}}} + "type": "object", + "required": ["name", "surprise"], + "properties": { + "name": {"type": "string", "description": "The name of user"}, + "alias": { + "type": "array", + "items": {"type": "string"}, + "description": "The list of user alias", + }, + "id": { + "type": "integer", + "description": "the id of user", + "readOnly": True, + }, + "surprise": {"type": "string"}, + "secret": {"type": "string", "readOnly": True}, + }, + } result = list(openapi20.convert_json_schema(schema)) def test_required_field_with_description(self): - assert ':