Skip to content

Commit

Permalink
Add integration tests for interacting with promises from native code.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdm committed Sep 22, 2016
1 parent ab16820 commit f89355b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 5 deletions.
46 changes: 42 additions & 4 deletions components/script/dom/testbinding.rs
Expand Up @@ -5,9 +5,10 @@
// check-tidy: no specs after this line

use core::nonzero::NonZero;
use dom::bindings::callback::ExceptionHandling;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::TestBindingBinding;
use dom::bindings::codegen::Bindings::TestBindingBinding::{self, SimpleCallback};
use dom::bindings::codegen::Bindings::TestBindingBinding::{TestBindingMethods, TestDictionary};
use dom::bindings::codegen::Bindings::TestBindingBinding::{TestDictionaryDefaults, TestEnum};
use dom::bindings::codegen::UnionTypes;
Expand All @@ -20,7 +21,7 @@ use dom::bindings::codegen::UnionTypes::{HTMLElementOrUnsignedLongOrStringOrBool
use dom::bindings::codegen::UnionTypes::{StringOrLongSequence, StringOrStringSequence, StringSequenceOrUnsignedLong};
use dom::bindings::codegen::UnionTypes::{StringOrUnsignedLong, StringOrBoolean, UnsignedLongOrBoolean};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::global::{GlobalRef, global_root_from_context};
use dom::bindings::js::Root;
use dom::bindings::mozmap::MozMap;
use dom::bindings::num::Finite;
Expand All @@ -29,6 +30,7 @@ use dom::bindings::str::{ByteString, DOMString, USVString};
use dom::bindings::weakref::MutableWeakRef;
use dom::blob::{Blob, BlobImpl};
use dom::promise::Promise;
use dom::promisenativehandler::{PromiseNativeHandler, Callback};
use dom::url::URL;
use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject};
use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray};
Expand Down Expand Up @@ -649,8 +651,44 @@ impl TestBindingMethods for TestBinding {
fn ReceiveAnyMozMap(&self) -> MozMap<JSVal> { MozMap::new() }

#[allow(unrooted_must_root)]
fn ReturnPromise(&self) -> Rc<Promise> {
Promise::new(self.global().r())
fn ReturnResolvedPromise(&self, cx: *mut JSContext, v: HandleValue) -> Fallible<Rc<Promise>> {
Promise::Resolve(self.global().r(), cx, v)
}

#[allow(unrooted_must_root)]
fn ReturnRejectedPromise(&self, cx: *mut JSContext, v: HandleValue) -> Fallible<Rc<Promise>> {
Promise::Reject(self.global().r(), cx, v)
}

#[allow(unrooted_must_root)]
fn PromiseNativeHandler(&self,
resolve: Option<Rc<SimpleCallback>>,
reject: Option<Rc<SimpleCallback>>) -> Rc<Promise> {
let global = self.global();
let handler = PromiseNativeHandler::new(global.r(),
resolve.map(|r| SimpleHandler::new(r)),
reject.map(|r| SimpleHandler::new(r)));
let p = Promise::new(global.r());
p.append_native_handler(&handler);
return p;

#[derive(JSTraceable, HeapSizeOf)]
struct SimpleHandler {
#[ignore_heap_size_of = "Rc has unclear ownership semantics"]
handler: Rc<SimpleCallback>,
}
impl SimpleHandler {
fn new(callback: Rc<SimpleCallback>) -> Box<Callback> {
box SimpleHandler { handler: callback }
}
}
impl Callback for SimpleHandler {
#[allow(unsafe_code)]
fn callback(&self, cx: *mut JSContext, v: HandleValue) {
let global = unsafe { global_root_from_context(cx) };
let _ = self.handler.Call_(&global.r(), v, ExceptionHandling::Report);
}
}
}

#[allow(unrooted_must_root)]
Expand Down
8 changes: 7 additions & 1 deletion components/script/dom/webidls/TestBinding.webidl
Expand Up @@ -508,14 +508,20 @@ interface TestBinding {
[Func="TestBinding::condition_satisfied"]
const unsigned short funcControlledConstEnabled = 0;

Promise<DOMString> returnPromise();
[Throws]
Promise<any> returnResolvedPromise(any value);
[Throws]
Promise<any> returnRejectedPromise(any value);
readonly attribute Promise<boolean> promiseAttribute;
void acceptPromise(Promise<DOMString> string);
void acceptNullablePromise(Promise<DOMString>? string);
Promise<any> promiseNativeHandler(SimpleCallback? resolve, SimpleCallback? reject);

void panic();
};

callback SimpleCallback = void(any value);

partial interface TestBinding {
[Pref="dom.testable_crash.enabled"]
void crashHard();
Expand Down
6 changes: 6 additions & 0 deletions tests/wpt/mozilla/meta/MANIFEST.json
Expand Up @@ -7176,6 +7176,12 @@
"url": "/_mozilla/mozilla/preserve_wrapper_callback.html"
}
],
"mozilla/promise.html": [
{
"path": "mozilla/promise.html",
"url": "/_mozilla/mozilla/promise.html"
}
],
"mozilla/prototypes.html": [
{
"path": "mozilla/prototypes.html",
Expand Down
3 changes: 3 additions & 0 deletions tests/wpt/mozilla/meta/mozilla/promise.html.ini
@@ -0,0 +1,3 @@
[promise.html]
type: testharness
prefs: [dom.testbinding.enabled:true]
40 changes: 40 additions & 0 deletions tests/wpt/mozilla/tests/mozilla/promise.html
@@ -0,0 +1,40 @@
<!doctype html>
<meta charset=utf-8>
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
promise_test(function() {
var t = new TestBinding;
return t.returnResolvedPromise('success')
.then(function(s) {
assert_equals(s, 'success');
});
}, 'Resolve callback gets argument');

promise_test(function(test) {
var t = new TestBinding;
return t.returnRejectedPromise('success')
.then(test.unreached_func())
.catch(function(s) {
assert_equals(s, 'success');
});
}, 'Reject callback gets argument');

promise_test(function(test) {
var t = new TestBinding;
var p = t.promiseNativeHandler(function(v) {
assert_equals(v, 'success');
}, null);
return Promise.resolve('success').then(p);
}, 'Native resolve callback gets argument');

promise_test(function(test) {
var t = new TestBinding;
var p = t.promiseNativeHandler(null, function(v) {
assert_equals(v, 'success');
});
p.then(test.unreached_func());
return Promise.resolve('success').then(p);
}, 'Native resolve callback gets argument');
</script>

0 comments on commit f89355b

Please sign in to comment.