Skip to content

Commit

Permalink
Add optional flag allowing wrapping responses in a parent class for J… (
Browse files Browse the repository at this point in the history
#192)

* Add optional flag allowing wrapping responses in a parent class for JS and TS client

- Adds the `--wrap-response-in` flag which allows users to pass in a value
- Response will be wrapped in the following way: `wrapper<type>` where `wrapper` is the string passed in with the flag, and `type` is the original response type
  • Loading branch information
rogebrd committed Oct 20, 2020
1 parent 75d4d3c commit 87ece6e
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 7 deletions.
15 changes: 14 additions & 1 deletion stone/backends/js_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
'The name will be added to each function documentation, which makes '
'it available for tools like JSDoc.'),
)
_cmdline_parser.add_argument(
'--wrap-response-in',
type=str,
default='',
help=('Wraps the response in a response class')
)

_header = """\
// Auto-generated by Stone, do not modify.
Expand Down Expand Up @@ -81,11 +87,18 @@ def _generate_route(self, route_schema, namespace, route):
if route.deprecated:
self.emit(' * @deprecated')

return_type = None
if self.args.wrap_response_in:
return_type = '%s<%s>' % (self.args.wrap_response_in,
fmt_type(route.result_data_type))
else:
return_type = fmt_type(route.result_data_type)

if route.arg_data_type.__class__ != Void:
self.emit(' * @arg {%s} arg - The request parameters.' %
fmt_type(route.arg_data_type))
self.emit(' * @returns {Promise.<%s, %s>}' %
(fmt_type(route.result_data_type),
(return_type,
fmt_error_type(route.error_data_type)))
self.emit(' */')

Expand Down
23 changes: 17 additions & 6 deletions stone/backends/tsd_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
default=2,
help=('Number of spaces to use per indentation level.')
)
_cmdline_parser.add_argument(
'--wrap-response-in',
type=str,
default='',
help=('Wraps the response in a response class')
)

_header = """\
// Auto-generated by Stone, do not modify.
Expand Down Expand Up @@ -126,13 +132,18 @@ def _generate_route(self, namespace, route):
self.emit(' * @param arg The request parameters.')
self.emit(' */')

if route.arg_data_type.__class__ != Void:
self.emit('public %s(arg: %s): Promise<%s>;' %
(function_name, fmt_type(route.arg_data_type),
fmt_type(route.result_data_type)))
return_type = None
if self.args.wrap_response_in:
return_type = 'Promise<%s<%s>>;' % (self.args.wrap_response_in,
fmt_type(route.result_data_type))
else:
self.emit('public %s(): Promise<%s>;' %
(function_name, fmt_type(route.result_data_type)))
return_type = 'Promise<%s>;' % (fmt_type(route.result_data_type))

arg = ''
if route.arg_data_type.__class__ != Void:
arg = 'arg: %s' % fmt_type(route.arg_data_type)

self.emit('public %s(%s): %s' % (function_name, arg, return_type))

def _docf(self, tag, val):
"""
Expand Down
46 changes: 46 additions & 0 deletions test/test_js_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,52 @@ def test_route_versions(self):
''')
assert result == expected

def test_wrap_response_in_flag(self):
# type: () -> None
api, _ = self._get_api()
backend = JavascriptClientBackend(
target_folder_path='output',
args=['files', '-c', 'DropboxBase', '--wrap-response-in', 'DropboxResponse'])
get_result = _mock_output(backend)
backend.generate(api)
result = get_result()

expected = textwrap.dedent('''\
// Auto-generated by Stone, do not modify.
var routes = {};
/**
* get_metadata
* @function DropboxBase#filesGetMetadata
* @returns {Promise.<DropboxResponse<void>, Error.<void>>}
*/
routes.filesGetMetadata = function () {
return this.request("files/get_metadata", null);
};
/**
* get_metadata_v2
* @function DropboxBase#filesGetMetadataV2
* @returns {Promise.<DropboxResponse<number>, Error.<void>>}
*/
routes.filesGetMetadataV2 = function () {
return this.request("files/get_metadata_v2", null);
};
/**
* get_metadata_v3
* @function DropboxBase#filesGetMetadataV3
* @arg {number} arg - The request parameters.
* @returns {Promise.<DropboxResponse<number>, Error.<void>>}
*/
routes.filesGetMetadataV3 = function (arg) {
return this.request("files/get_metadata_v3", arg);
};
export { routes };
''')
assert result == expected

def test_route_with_version_number_conflict(self):
# type: () -> None
api, ns = self._get_api()
Expand Down
36 changes: 36 additions & 0 deletions test/test_tsd_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,42 @@ def test__generate_types_single_ns(self):
''')
self.assertEqual(result, expected)

def test__generate_types_with_wrap_response_flag(self):
# type: () -> None
api, _ = self._get_api()
backend = TSDClientBackend(
target_folder_path="output",
args=['files', 'files', '--wrap-response-in', 'DropboxResponse']
)
backend._generate_routes(api, 0, 0)
result = backend.output_buffer_to_string()
expected = textwrap.dedent(
'''\
/**
* getMetadata()
*
* When an error occurs, the route rejects the promise with type Error<void>.
*/
public filesGetMetadata(): Promise<DropboxResponse<void>>;
/**
* getMetadataV2()
*
* When an error occurs, the route rejects the promise with type Error<void>.
*/
public filesGetMetadataV2(): Promise<DropboxResponse<number>>;
/**
* getMetadataV3()
*
* When an error occurs, the route rejects the promise with type Error<void>.
* @param arg The request parameters.
*/
public filesGetMetadataV3(arg: number): Promise<DropboxResponse<number>>;
''')
self.assertEqual(result, expected)

def test_route_with_version_number_conflict(self):
# type: () -> None
api, ns = self._get_api()
Expand Down

0 comments on commit 87ece6e

Please sign in to comment.