diff --git a/bddrest/authoring/given.py b/bddrest/authoring/given.py index 27d9c78..c4491a7 100644 --- a/bddrest/authoring/given.py +++ b/bddrest/authoring/given.py @@ -4,32 +4,23 @@ from .story import Story -# TODO: add autodoc_format argumnet - - class Given(Story, Context): """ :param application: A WSGI Application to examine. :param autodump: A file-like object to write dumped story. Default is `None`, means autodump is disabled by default. - :param autodoc: A file-like object to write documentation. - Default is `None`, meana autodoc is disabled by default. - :param autodoc_format: Either ``markdown`` or ``html``. default is - ``markdown``. - :param fieldinfo: A callable(resource, verb, fieldname) to provide the - field's metadata. + :param autodoc: A dictionary to pass to :class:`Documenter` and enable + auto documentary. See :class:`Story` for other arguments. """ def __init__(self, application, *args, autodump=None, autodoc=None, - autodoc_format='markdown', fieldinfo=None, **kwargs): + **kwargs): self.application = application self.autodump = autodump self.autodoc = autodoc - self.autodoc_format = autodoc_format - self.fieldinfo = fieldinfo base_call = FirstCall(*args, **kwargs) base_call.conclude(application) super().__init__(base_call) @@ -71,11 +62,7 @@ def __exit__(self, exc_type, exc_value, traceback): self.dump(self.autodump) if self.autodoc: - self.document( - self.autodoc, - format_=self.autodoc_format, - fieldinfo=self.fieldinfo - ) + self.document(**self.autodoc) @property def response(self): diff --git a/bddrest/authoring/story.py b/bddrest/authoring/story.py index ffe2355..aaf4254 100644 --- a/bddrest/authoring/story.py +++ b/bddrest/authoring/story.py @@ -64,9 +64,9 @@ def validate(self): for call in self.calls: call.validate() - def document(self, outfile, format_='markdown', **kw): - documenter = Documenter(format_, **kw) - documenter.document(self, outfile) + def document(self, file, **kwargs): + documenter = Documenter(**kwargs) + documenter.document(self, file) @property def title(self): diff --git a/bddrest/documentary/cli.py b/bddrest/documentary/cli.py index faf703b..86206b7 100644 --- a/bddrest/documentary/cli.py +++ b/bddrest/documentary/cli.py @@ -21,5 +21,6 @@ def __call__(self, args): def convert_file(self, source, outfile, format_): from ..authoring import Story + story = Story.load(source) - story.document(outfile, format_=format_) + story.document(outfile, format=format_) diff --git a/bddrest/documentary/documenter.py b/bddrest/documentary/documenter.py index 9ebe2bf..136466d 100644 --- a/bddrest/documentary/documenter.py +++ b/bddrest/documentary/documenter.py @@ -5,9 +5,10 @@ class Documenter: - def __init__(self, format_, fieldinfo=None): - self.format_ = format_ - self.fieldinfo = fieldinfo + def __init__(self, format='markdown', oncall=None, onfield=None): + self.format = format + self.oncall = oncall + self.onfield = onfield def write_response(self, formatter, response): formatter.write_header(f'Response: {response.status}', 3) @@ -35,6 +36,9 @@ def write_curl(self, formatter, content): def write_call(self, basecall, call, formatter): + if self.oncall: + self.oncall(call) + formatter.write_header(f'{call.verb} {call.url}', 3) if call.description: @@ -66,25 +70,23 @@ def write_call(self, basecall, call, formatter): formatter.write_header('Form', 3) rows = [] for k, value in call.form.items(): - info = self.fieldinfo(call.url, call.verb, k) \ - if self.fieldinfo else None + info = self.onfield(call, k) if self.onfield else {} + if info is None: + info = {} for v in value: - info = info or {} needed = info.get('required') - notnone = info.get('not_none') type_ = info.get('type') rows.append(( k, '?' if needed is None else needed and 'Yes' or 'No', - '?' if notnone is None else notnone and 'No' or 'Yes', '?' if type_ is None else type_, v )) formatter.write_table( rows, - headers=('Name', 'Required', 'Nullable', 'Type', 'Example') + headers=('Name', 'Required', 'Type', 'Example') ) if call.multipart \ @@ -92,24 +94,22 @@ def write_call(self, basecall, call, formatter): formatter.write_header('Multipart', 3) rows = [] for k, v in call.multipart.items(): - info = self.fieldinfo(call.url, call.verb, k) \ - if self.fieldinfo else None + info = self.onfield(call, k) if self.onfield else {} + if info is None: + info = {} - info = info or {} required = info.get('required') - not_none = info.get('not_none') type_ = info.get('type') rows.append(( k, '?' if required is None else required and 'Yes' or 'No', - '?' if not_none is None else not_none and 'No' or 'Yes', '?' if type_ is None else type_, v if not isinstance(v, io.BytesIO) else '', )) formatter.write_table( rows, - headers=('Name', 'Required', 'Nullable', 'Type', 'Example') + headers=('Name', 'Required', 'Type', 'Example') ) if call.json and not isinstance(call.json, list) \ @@ -117,10 +117,7 @@ def write_call(self, basecall, call, formatter): formatter.write_header('Form', 3) rows = [] for k, v in call.json.items(): - info = self.fieldinfo(call.url, call.verb, k) \ - if self.fieldinfo else None - - info = info or {} + info = self.onfield(call, k) if self.onfield else {} required = info.get('required') not_none = info.get('not_none') type_ = info.get('type') @@ -149,7 +146,7 @@ def write_call(self, basecall, call, formatter): def document(self, story, outfile): basecall = story.base_call - formatter = createformatter(self.format_, outfile) + formatter = createformatter(self.format, outfile) formatter.write_header(basecall.title.capitalize(), 2) self.write_call(None, basecall, formatter) diff --git a/tests/test_autodocumentation.py b/tests/test_autodocumentation.py index 9ab2a02..0e348ef 100644 --- a/tests/test_autodocumentation.py +++ b/tests/test_autodocumentation.py @@ -14,7 +14,7 @@ def test_autodoc_file_object(): wsgi_application, title='Testing auto documentation', url='/apiv1/devices/name: SM-12345678', - autodoc=file, + autodoc=dict(file=file), ): assert response.status == 200 diff --git a/tests/test_cli.py b/tests/test_cli.py index b1c03fd..09cc12a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -68,9 +68,9 @@ def test_help(): ### Form -Name | Required | Nullable | Type | Example ---- | --- | --- | --- | --- -name | ? | ? | ? | BDD Book +Name | Required | Type | Example +--- | --- | --- | --- +name | ? | ? | BDD Book ### CURL diff --git a/tests/test_documentary_html.py b/tests/test_documentary_html.py index 68a28db..ebabce3 100644 --- a/tests/test_documentary_html.py +++ b/tests/test_documentary_html.py @@ -5,14 +5,14 @@ def test_html(): - def get_field_info(resource, verb, name): + def get_field_info(call, name): return dict( f1=dict(required=True, not_none=True, type='str'), ).get(name) story = Story.loads(provided_story) outfile = io.StringIO() - story.document(outfile, fieldinfo=get_field_info, format_='html') + story.document(outfile, onfield=get_field_info, format='html') outputstring = outfile.getvalue() assert expected_html == outputstring @@ -131,9 +131,6 @@ def get_field_info(resource, verb, name): Required -Nullable - - Type @@ -148,9 +145,6 @@ def get_field_info(resource, verb, name): Yes -No - - str @@ -168,9 +162,6 @@ def get_field_info(resource, verb, name): ? -? - - 123 @@ -277,9 +268,6 @@ def get_field_info(resource, verb, name): Required -Nullable - - Type @@ -294,9 +282,6 @@ def get_field_info(resource, verb, name): Yes -No - - str diff --git a/tests/test_documentary_markdown.py b/tests/test_documentary_markdown.py index c0e2911..7ed0565 100644 --- a/tests/test_documentary_markdown.py +++ b/tests/test_documentary_markdown.py @@ -5,14 +5,14 @@ def test_markdown(): - def get_field_info(resource, verb, name): + def get_field_info(call, name): return dict( f1=dict(required=True, not_none=True, type='str'), ).get(name) story = Story.loads(provided_story) outfile = io.StringIO() - story.document(outfile, fieldinfo=get_field_info) + story.document(outfile, onfield=get_field_info) outputstring = outfile.getvalue() assert expected_markdown == outputstring @@ -81,10 +81,10 @@ def get_field_info(resource, verb, name): ### Form -Name | Required | Nullable | Type | Example ---- | --- | --- | --- | --- -f1 | Yes | No | str | abc -f2 | ? | ? | ? | 123 +Name | Required | Type | Example +--- | --- | --- | --- +f1 | Yes | str | abc +f2 | ? | ? | 123 ### Request Headers @@ -129,9 +129,9 @@ def get_field_info(resource, verb, name): ### Form -Name | Required | Nullable | Type | Example ---- | --- | --- | --- | --- -f1 | Yes | No | str | cba +Name | Required | Type | Example +--- | --- | --- | --- +f1 | Yes | str | cba ### Request Headers diff --git a/tests/test_multipart_form.py b/tests/test_multipart_form.py index 0a38fbf..c4e5a0d 100644 --- a/tests/test_multipart_form.py +++ b/tests/test_multipart_form.py @@ -36,9 +36,9 @@ def wsgi_application(environ, start_response): ### Multipart -Name | Required | Nullable | Type | Example ---- | --- | --- | --- | --- -a | ? | ? | ? | +Name | Required | Type | Example +--- | --- | --- | --- +a | ? | ? | ### CURL