Increase OAS description
Parce docstring of http handlers to increase OAS Remove the not expected definitions key in the OAS
This commit is contained in:
1
tests/test_oas/test_cmd/oas_base.json
Normal file
1
tests/test_oas/test_cmd/oas_base.json
Normal file
@@ -0,0 +1 @@
|
||||
{"info": {"title": "MyApp", "version": "1.0.0"}}
|
||||
@@ -1,10 +1,13 @@
|
||||
import argparse
|
||||
from textwrap import dedent
|
||||
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from aiohttp_pydantic.oas import cmd
|
||||
|
||||
PATH_TO_BASE_JSON_FILE = str(Path(__file__).parent / "oas_base.json")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cmd_line():
|
||||
@@ -13,10 +16,11 @@ def cmd_line():
|
||||
return parser
|
||||
|
||||
|
||||
def test_show_oad_of_app(cmd_line, capfd):
|
||||
def test_show_oas_of_app(cmd_line):
|
||||
args = cmd_line.parse_args(["tests.test_oas.test_cmd.sample"])
|
||||
args.output = StringIO()
|
||||
args.func(args)
|
||||
captured = capfd.readouterr()
|
||||
|
||||
expected = dedent(
|
||||
"""
|
||||
{
|
||||
@@ -57,13 +61,13 @@ def test_show_oad_of_app(cmd_line, capfd):
|
||||
"""
|
||||
)
|
||||
|
||||
assert captured.out.strip() == expected.strip()
|
||||
assert args.output.getvalue().strip() == expected.strip()
|
||||
|
||||
|
||||
def test_show_oad_of_sub_app(cmd_line, capfd):
|
||||
def test_show_oas_of_sub_app(cmd_line):
|
||||
args = cmd_line.parse_args(["tests.test_oas.test_cmd.sample:sub_app"])
|
||||
args.output = StringIO()
|
||||
args.func(args)
|
||||
captured = capfd.readouterr()
|
||||
expected = dedent(
|
||||
"""
|
||||
{
|
||||
@@ -89,16 +93,26 @@ def test_show_oad_of_sub_app(cmd_line, capfd):
|
||||
"""
|
||||
)
|
||||
|
||||
assert captured.out.strip() == expected.strip()
|
||||
assert args.output.getvalue().strip() == expected.strip()
|
||||
|
||||
|
||||
def test_show_oad_of_a_callable(cmd_line, capfd):
|
||||
args = cmd_line.parse_args(["tests.test_oas.test_cmd.sample:make_app()"])
|
||||
def test_show_oas_of_a_callable(cmd_line):
|
||||
args = cmd_line.parse_args(
|
||||
[
|
||||
"tests.test_oas.test_cmd.sample:make_app()",
|
||||
"--base-oas-file",
|
||||
PATH_TO_BASE_JSON_FILE,
|
||||
]
|
||||
)
|
||||
args.output = StringIO()
|
||||
args.func(args)
|
||||
captured = capfd.readouterr()
|
||||
expected = dedent(
|
||||
"""
|
||||
{
|
||||
"info": {
|
||||
"title": "MyApp",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/route-3/{a}": {
|
||||
@@ -121,4 +135,4 @@ def test_show_oad_of_a_callable(cmd_line, capfd):
|
||||
"""
|
||||
)
|
||||
|
||||
assert captured.out.strip() == expected.strip()
|
||||
assert args.output.getvalue().strip() == expected.strip()
|
||||
|
||||
88
tests/test_oas/test_docstring_parser.py
Normal file
88
tests/test_oas/test_docstring_parser.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from aiohttp_pydantic.oas.docstring_parser import (
|
||||
status_code,
|
||||
operation,
|
||||
_i_extract_block,
|
||||
LinesIterator,
|
||||
)
|
||||
from inspect import getdoc
|
||||
import pytest
|
||||
|
||||
|
||||
def web_handler():
|
||||
"""
|
||||
bla bla bla
|
||||
|
||||
|
||||
Status Codes:
|
||||
200: line 1
|
||||
|
||||
line 2:
|
||||
- line 3
|
||||
- line 4
|
||||
|
||||
line 5
|
||||
|
||||
300: line A 1
|
||||
|
||||
301: line B 1
|
||||
line B 2
|
||||
400: line C 1
|
||||
|
||||
line C 2
|
||||
|
||||
line C 3
|
||||
|
||||
bla bla
|
||||
"""
|
||||
|
||||
|
||||
def test_lines_iterator():
|
||||
lines_iterator = LinesIterator("AAAA\nBBBB")
|
||||
with pytest.raises(StopIteration):
|
||||
lines_iterator.rewind()
|
||||
|
||||
assert lines_iterator.next_line() == "AAAA"
|
||||
assert lines_iterator.rewind()
|
||||
assert lines_iterator.next_line() == "AAAA"
|
||||
assert lines_iterator.next_line() == "BBBB"
|
||||
with pytest.raises(StopIteration):
|
||||
lines_iterator.next_line()
|
||||
|
||||
|
||||
def test_status_code():
|
||||
|
||||
expected = {
|
||||
200: "line 1\n\nline 2:\n - line 3\n - line 4\n\nline 5",
|
||||
300: "line A 1",
|
||||
301: "line B 1\nline B 2",
|
||||
400: "line C 1\n\nline C 2\n\n line C 3",
|
||||
}
|
||||
|
||||
assert status_code(getdoc(web_handler)) == expected
|
||||
|
||||
|
||||
def test_operation():
|
||||
expected = "bla bla bla\n\n\nbla bla"
|
||||
assert operation(getdoc(web_handler)) == expected
|
||||
|
||||
|
||||
def test_i_extract_block():
|
||||
lines = LinesIterator(" aaaa\n\n bbbb\n\n cccc\n dddd")
|
||||
text = "\n".join(_i_extract_block(lines))
|
||||
assert text == """aaaa\n\n bbbb\n\ncccc"""
|
||||
|
||||
lines = LinesIterator("")
|
||||
text = "\n".join(_i_extract_block(lines))
|
||||
assert text == ""
|
||||
|
||||
lines = LinesIterator("aaaa\n bbbb") # the indented block is cut by a new block
|
||||
text = "\n".join(_i_extract_block(lines))
|
||||
assert text == ""
|
||||
|
||||
lines = LinesIterator(" \n ")
|
||||
text = "\n".join(_i_extract_block(lines))
|
||||
assert text == ""
|
||||
|
||||
lines = LinesIterator(" aaaa\n bbbb")
|
||||
text = "\n".join(_i_extract_block(lines))
|
||||
assert text == "aaaa\nbbbb"
|
||||
@@ -33,6 +33,9 @@ class PetCollectionView(PydanticView):
|
||||
) -> r200[List[Pet]]:
|
||||
"""
|
||||
Get a list of pets
|
||||
|
||||
Status Codes:
|
||||
200: Successful operation
|
||||
"""
|
||||
return web.json_response()
|
||||
|
||||
@@ -49,6 +52,19 @@ class PetItemView(PydanticView):
|
||||
return web.json_response()
|
||||
|
||||
async def delete(self, id: int, /) -> r204:
|
||||
"""
|
||||
Status Code:
|
||||
204: Empty but OK
|
||||
"""
|
||||
return web.json_response()
|
||||
|
||||
|
||||
class TestResponseReturnASimpleType(PydanticView):
|
||||
async def get(self) -> r200[int]:
|
||||
"""
|
||||
Status Codes:
|
||||
200: The new number
|
||||
"""
|
||||
return web.json_response()
|
||||
|
||||
|
||||
@@ -57,6 +73,7 @@ async def generated_oas(aiohttp_client, loop) -> web.Application:
|
||||
app = web.Application()
|
||||
app.router.add_view("/pets", PetCollectionView)
|
||||
app.router.add_view("/pets/{id}", PetItemView)
|
||||
app.router.add_view("/simple-type", TestResponseReturnASimpleType)
|
||||
oas.setup(app)
|
||||
|
||||
client = await aiohttp_client(app)
|
||||
@@ -115,29 +132,11 @@ async def test_pets_route_should_have_get_method(generated_oas):
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful operation",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"items": {
|
||||
"definitions": {
|
||||
"Color": {
|
||||
"description": "An enumeration.",
|
||||
"enum": ["red", "green", "pink"],
|
||||
"title": "Color",
|
||||
"type": "string",
|
||||
},
|
||||
"Toy": {
|
||||
"properties": {
|
||||
"color": {
|
||||
"$ref": "#/components/schemas/Color"
|
||||
},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
},
|
||||
"required": ["name", "color"],
|
||||
"title": "Toy",
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "integer"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
@@ -154,7 +153,7 @@ async def test_pets_route_should_have_get_method(generated_oas):
|
||||
"type": "array",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -167,23 +166,6 @@ async def test_pets_route_should_have_post_method(generated_oas):
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"Color": {
|
||||
"description": "An enumeration.",
|
||||
"enum": ["red", "green", "pink"],
|
||||
"title": "Color",
|
||||
"type": "string",
|
||||
},
|
||||
"Toy": {
|
||||
"properties": {
|
||||
"color": {"$ref": "#/components/schemas/Color"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
},
|
||||
"required": ["name", "color"],
|
||||
"title": "Toy",
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "integer"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
@@ -202,26 +184,10 @@ async def test_pets_route_should_have_post_method(generated_oas):
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"Color": {
|
||||
"description": "An enumeration.",
|
||||
"enum": ["red", "green", "pink"],
|
||||
"title": "Color",
|
||||
"type": "string",
|
||||
},
|
||||
"Toy": {
|
||||
"properties": {
|
||||
"color": {"$ref": "#/components/schemas/Color"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
},
|
||||
"required": ["name", "color"],
|
||||
"title": "Toy",
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "integer"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
@@ -236,7 +202,7 @@ async def test_pets_route_should_have_post_method(generated_oas):
|
||||
"type": "object",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -248,15 +214,16 @@ async def test_generated_oas_should_have_pets_id_paths(generated_oas):
|
||||
|
||||
async def test_pets_id_route_should_have_delete_method(generated_oas):
|
||||
assert generated_oas["paths"]["/pets/{id}"]["delete"] == {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"required": True,
|
||||
"schema": {"title": "id", "type": "integer"},
|
||||
}
|
||||
],
|
||||
"responses": {"204": {"content": {}}},
|
||||
"responses": {"204": {"content": {}, "description": "Empty but OK"}},
|
||||
}
|
||||
|
||||
|
||||
@@ -272,26 +239,10 @@ async def test_pets_id_route_should_have_get_method(generated_oas):
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"Color": {
|
||||
"description": "An enumeration.",
|
||||
"enum": ["red", "green", "pink"],
|
||||
"title": "Color",
|
||||
"type": "string",
|
||||
},
|
||||
"Toy": {
|
||||
"properties": {
|
||||
"color": {"$ref": "#/components/schemas/Color"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
},
|
||||
"required": ["name", "color"],
|
||||
"title": "Toy",
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "integer"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
@@ -306,9 +257,9 @@ async def test_pets_id_route_should_have_get_method(generated_oas):
|
||||
"type": "object",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"404": {"content": {}},
|
||||
"404": {"description": "", "content": {}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -327,23 +278,6 @@ async def test_pets_id_route_should_have_put_method(generated_oas):
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"definitions": {
|
||||
"Color": {
|
||||
"description": "An enumeration.",
|
||||
"enum": ["red", "green", "pink"],
|
||||
"title": "Color",
|
||||
"type": "string",
|
||||
},
|
||||
"Toy": {
|
||||
"properties": {
|
||||
"color": {"$ref": "#/components/schemas/Color"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
},
|
||||
"required": ["name", "color"],
|
||||
"title": "Toy",
|
||||
"type": "object",
|
||||
},
|
||||
},
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "integer"},
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
@@ -361,3 +295,15 @@ async def test_pets_id_route_should_have_put_method(generated_oas):
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
async def test_simple_type_route_should_have_get_method(generated_oas):
|
||||
assert generated_oas["paths"]["/simple-type"]["get"] == {
|
||||
"description": "",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
"description": "The new number",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user