Commit 2a8f296e authored by Sam Thorogood's avatar Sam Thorogood Committed by Chromium LUCI CQ

Add can_return_promise to Function model, adds test.

This will control whether we document a Promise-ified version of an API.
(Chrome's implementation CPP already pierces into the JSON directly to answer the support Q.)

Bug: 1142991
Bug: 1143020
Change-Id: I1a3c29c7d1c21cc52b55b88db12478e4b1e14811
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2569130Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Commit-Queue: Sam Thorogood <thorogood@google.com>
Cr-Commit-Position: refs/heads/master@{#843249}
parent 27cdf4f7
...@@ -380,7 +380,7 @@ class Function(object): ...@@ -380,7 +380,7 @@ class Function(object):
raise ValueError('Only a single parameter can be specific on ' raise ValueError('Only a single parameter can be specific on '
'returns_async: %s.%s' % (namespace.name, name)) 'returns_async: %s.%s' % (namespace.name, name))
self.returns_async = ReturnsAsync(self, returns_async, namespace, self.returns_async = ReturnsAsync(self, returns_async, namespace,
Origin(from_client=True)) Origin(from_client=True), True)
# TODO(https://crbug.com/1143032): Returning a synchronous value is # TODO(https://crbug.com/1143032): Returning a synchronous value is
# incompatible with returning a promise. There are APIs that specify this, # incompatible with returning a promise. There are APIs that specify this,
# though. Some appear to be incorrectly specified (i.e., don't return a # though. Some appear to be incorrectly specified (i.e., don't return a
...@@ -406,8 +406,12 @@ class Function(object): ...@@ -406,8 +406,12 @@ class Function(object):
self.params.append(GeneratePropertyFromParam(param)) self.params.append(GeneratePropertyFromParam(param))
if callback_param: if callback_param:
# Even though we are creating a ReturnsAsync type here, this does not
# support being returned via a Promise, as this is implied by
# "returns_async" being found in the JSON.
# This is just a holder type for the callback.
self.returns_async = ReturnsAsync(self, callback_param, namespace, self.returns_async = ReturnsAsync(self, callback_param, namespace,
Origin(from_client=True)) Origin(from_client=True), False)
self.returns = None self.returns = None
if 'returns' in json: if 'returns' in json:
...@@ -432,14 +436,17 @@ class ReturnsAsync(object): ...@@ -432,14 +436,17 @@ class ReturnsAsync(object):
- |params| a list of parameters supplied to the function in the case of using - |params| a list of parameters supplied to the function in the case of using
callbacks, or the list of properties on the returned object in the callbacks, or the list of properties on the returned object in the
case of using promises case of using promises
- |can_return_promise| whether this can be treated as a Promise as well as
callback
""" """
def __init__(self, parent, json, namespace, origin): def __init__(self, parent, json, namespace, origin, can_return_promise):
self.name = json.get('name') self.name = json.get('name')
self.simple_name = _StripNamespace(self.name, namespace) self.simple_name = _StripNamespace(self.name, namespace)
self.description = json.get('description') self.description = json.get('description')
self.optional = json.get('optional', False) self.optional = json.get('optional', False)
self.nocompile = json.get('nocompile') self.nocompile = json.get('nocompile')
self.parent = parent self.parent = parent
self.can_return_promise = can_return_promise
if json.get('returns') is not None: if json.get('returns') is not None:
raise ValueError('Cannot return a value from an asynchronous return: ' raise ValueError('Cannot return a value from an asynchronous return: '
......
...@@ -40,6 +40,10 @@ class ModelTest(unittest.TestCase): ...@@ -40,6 +40,10 @@ class ModelTest(unittest.TestCase):
'path/to/idl_namespace_non_specific_platforms.idl') 'path/to/idl_namespace_non_specific_platforms.idl')
self.idl_namespace_non_specific_platforms = self.model.namespaces.get( self.idl_namespace_non_specific_platforms = self.model.namespaces.get(
'idl_namespace_non_specific_platforms') 'idl_namespace_non_specific_platforms')
self.returns_async_json = CachedLoad('test/returns_async.json')
self.model.AddNamespace(self.returns_async_json[0],
'path/to/returns_async.json')
self.returns_async = self.model.namespaces.get('returns_async')
self.nodoc_json = CachedLoad('test/namespace_nodoc.json') self.nodoc_json = CachedLoad('test/namespace_nodoc.json')
self.model.AddNamespace(self.nodoc_json[0], self.model.AddNamespace(self.nodoc_json[0],
'path/to/namespace_nodoc.json') 'path/to/namespace_nodoc.json')
...@@ -50,7 +54,7 @@ class ModelTest(unittest.TestCase): ...@@ -50,7 +54,7 @@ class ModelTest(unittest.TestCase):
self.fakeapi = self.model.namespaces.get('fakeapi') self.fakeapi = self.model.namespaces.get('fakeapi')
def testNamespaces(self): def testNamespaces(self):
self.assertEquals(8, len(self.model.namespaces)) self.assertEquals(9, len(self.model.namespaces))
self.assertTrue(self.permissions) self.assertTrue(self.permissions)
def testHasFunctions(self): def testHasFunctions(self):
...@@ -106,6 +110,12 @@ class ModelTest(unittest.TestCase): ...@@ -106,6 +110,12 @@ class ModelTest(unittest.TestCase):
'True if the extension has the specified permissions.', self. 'True if the extension has the specified permissions.', self.
permissions.functions['contains'].returns_async.params[0].description) permissions.functions['contains'].returns_async.params[0].description)
def testAsyncPromise(self):
returnsFunction = self.returns_async.functions['returnsObject']
self.assertTrue(returnsFunction.returns_async.can_return_promise)
callbackFunction = self.returns_async.functions['callbackObject']
self.assertFalse(callbackFunction.returns_async.can_return_promise)
def testPropertyUnixName(self): def testPropertyUnixName(self):
param = self.tabs.functions['move'].params[0] param = self.tabs.functions['move'].params[0]
self.assertEquals('tab_ids', param.unix_name) self.assertEquals('tab_ids', param.unix_name)
......
...@@ -28,6 +28,28 @@ ...@@ -28,6 +28,28 @@
} }
] ]
} }
},
{
"name": "callbackObject",
"description": "Returns an object via callback.",
"type": "function",
"parameters": [
{
"name": "callback",
"type": "function",
"parameters": [
{
"name": "someObject",
"type": "object",
"properties": {
"state": {
"$ref": "Enumeration"
}
}
}
]
}
]
} }
] ]
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment