1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "bindings/core/v8/ScriptPromiseResolver.h"
8 #include "bindings/core/v8/ScriptFunction.h"
9 #include "bindings/core/v8/ScriptValue.h"
10 #include "bindings/core/v8/V8Binding.h"
11 #include "core/dom/DOMException.h"
12 #include "core/dom/Document.h"
13 #include "core/dom/ExceptionCode.h"
14 #include "core/testing/DummyPageHolder.h"
16 #include <gtest/gtest.h>
23 void callback(const v8::FunctionCallbackInfo<v8::Value>& info) { }
25 class Function : public ScriptFunction {
27 static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, String* value)
29 Function* self = new Function(scriptState, value);
30 return self->bindToV8Function();
34 Function(ScriptState* scriptState, String* value)
35 : ScriptFunction(scriptState)
40 virtual ScriptValue call(ScriptValue value) OVERRIDE
42 ASSERT(!value.isEmpty());
43 *m_value = toCoreString(value.v8Value()->ToString());
50 class ScriptPromiseResolverTest : public ::testing::Test {
52 ScriptPromiseResolverTest()
53 : m_pageHolder(DummyPageHolder::create())
57 virtual ~ScriptPromiseResolverTest()
59 ScriptState::Scope scope(scriptState());
60 // FIXME: We put this statement here to clear an exception from the
62 createClosure(callback, v8::Undefined(isolate()), isolate());
64 // Execute all pending microtasks
65 isolate()->RunMicrotasks();
68 OwnPtr<DummyPageHolder> m_pageHolder;
69 ScriptState* scriptState() const { return ScriptState::forMainWorld(&m_pageHolder->frame()); }
70 ExecutionContext* executionContext() const { return &m_pageHolder->document(); }
71 v8::Isolate* isolate() const { return scriptState()->isolate(); }
74 TEST_F(ScriptPromiseResolverTest, construct)
76 ASSERT_FALSE(executionContext()->activeDOMObjectsAreStopped());
77 ScriptState::Scope scope(scriptState());
78 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState());
81 TEST_F(ScriptPromiseResolverTest, resolve)
83 RefPtr<ScriptPromiseResolver> resolver;
84 ScriptPromise promise;
86 ScriptState::Scope scope(scriptState());
87 resolver = ScriptPromiseResolver::create(scriptState());
88 promise = resolver->promise();
91 String onFulfilled, onRejected;
92 ASSERT_FALSE(promise.isEmpty());
94 ScriptState::Scope scope(scriptState());
95 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
98 EXPECT_EQ(String(), onFulfilled);
99 EXPECT_EQ(String(), onRejected);
101 isolate()->RunMicrotasks();
103 EXPECT_EQ(String(), onFulfilled);
104 EXPECT_EQ(String(), onRejected);
106 resolver->resolve("hello");
109 ScriptState::Scope scope(scriptState());
110 EXPECT_TRUE(resolver->promise().isEmpty());
113 EXPECT_EQ(String(), onFulfilled);
114 EXPECT_EQ(String(), onRejected);
116 isolate()->RunMicrotasks();
118 EXPECT_EQ("hello", onFulfilled);
119 EXPECT_EQ(String(), onRejected);
121 resolver->resolve("bye");
122 resolver->reject("bye");
123 isolate()->RunMicrotasks();
125 EXPECT_EQ("hello", onFulfilled);
126 EXPECT_EQ(String(), onRejected);
129 TEST_F(ScriptPromiseResolverTest, reject)
131 RefPtr<ScriptPromiseResolver> resolver;
132 ScriptPromise promise;
134 ScriptState::Scope scope(scriptState());
135 resolver = ScriptPromiseResolver::create(scriptState());
136 promise = resolver->promise();
139 String onFulfilled, onRejected;
140 ASSERT_FALSE(promise.isEmpty());
142 ScriptState::Scope scope(scriptState());
143 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
146 EXPECT_EQ(String(), onFulfilled);
147 EXPECT_EQ(String(), onRejected);
149 isolate()->RunMicrotasks();
151 EXPECT_EQ(String(), onFulfilled);
152 EXPECT_EQ(String(), onRejected);
154 resolver->reject("hello");
157 ScriptState::Scope scope(scriptState());
158 EXPECT_TRUE(resolver->promise().isEmpty());
161 EXPECT_EQ(String(), onFulfilled);
162 EXPECT_EQ(String(), onRejected);
164 isolate()->RunMicrotasks();
166 EXPECT_EQ(String(), onFulfilled);
167 EXPECT_EQ("hello", onRejected);
169 resolver->resolve("bye");
170 resolver->reject("bye");
171 isolate()->RunMicrotasks();
173 EXPECT_EQ(String(), onFulfilled);
174 EXPECT_EQ("hello", onRejected);
177 TEST_F(ScriptPromiseResolverTest, stop)
179 RefPtr<ScriptPromiseResolver> resolver;
180 ScriptPromise promise;
182 ScriptState::Scope scope(scriptState());
183 resolver = ScriptPromiseResolver::create(scriptState());
184 promise = resolver->promise();
187 String onFulfilled, onRejected;
188 ASSERT_FALSE(promise.isEmpty());
190 ScriptState::Scope scope(scriptState());
191 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
194 executionContext()->stopActiveDOMObjects();
196 ScriptState::Scope scope(scriptState());
197 EXPECT_TRUE(resolver->promise().isEmpty());
200 resolver->resolve("hello");
201 isolate()->RunMicrotasks();
203 EXPECT_EQ(String(), onFulfilled);
204 EXPECT_EQ(String(), onRejected);
207 TEST_F(ScriptPromiseResolverTest, keepAliveUntilResolved)
209 RefPtr<ScriptPromiseResolver> resolver;
211 ScriptState::Scope scope(scriptState());
212 resolver = ScriptPromiseResolver::create(scriptState());
214 EXPECT_EQ(1, resolver->refCount());
215 resolver->keepAliveWhilePending();
216 EXPECT_EQ(2, resolver->refCount());
218 resolver->resolve("hello");
219 EXPECT_EQ(1, resolver->refCount());
222 TEST_F(ScriptPromiseResolverTest, keepAliveUntilRejected)
224 RefPtr<ScriptPromiseResolver> resolver;
226 ScriptState::Scope scope(scriptState());
227 resolver = ScriptPromiseResolver::create(scriptState());
229 EXPECT_EQ(1, resolver->refCount());
230 resolver->keepAliveWhilePending();
231 EXPECT_EQ(2, resolver->refCount());
233 resolver->reject("hello");
234 EXPECT_EQ(1, resolver->refCount());
237 TEST_F(ScriptPromiseResolverTest, keepAliveUntilStopped)
239 RefPtr<ScriptPromiseResolver> resolver;
241 ScriptState::Scope scope(scriptState());
242 resolver = ScriptPromiseResolver::create(scriptState());
244 EXPECT_EQ(1, resolver->refCount());
245 resolver->keepAliveWhilePending();
246 EXPECT_EQ(2, resolver->refCount());
248 executionContext()->stopActiveDOMObjects();
249 EXPECT_EQ(1, resolver->refCount());
252 TEST_F(ScriptPromiseResolverTest, suspend)
254 RefPtr<ScriptPromiseResolver> resolver;
256 ScriptState::Scope scope(scriptState());
257 resolver = ScriptPromiseResolver::create(scriptState());
259 EXPECT_EQ(1, resolver->refCount());
260 resolver->keepAliveWhilePending();
261 EXPECT_EQ(2, resolver->refCount());
262 executionContext()->suspendActiveDOMObjects();
263 resolver->resolve("hello");
264 EXPECT_EQ(3, resolver->refCount());
266 executionContext()->stopActiveDOMObjects();
267 EXPECT_EQ(1, resolver->refCount());
270 TEST_F(ScriptPromiseResolverTest, resolveVoid)
272 RefPtr<ScriptPromiseResolver> resolver;
273 ScriptPromise promise;
275 ScriptState::Scope scope(scriptState());
276 resolver = ScriptPromiseResolver::create(scriptState());
277 promise = resolver->promise();
280 String onFulfilled, onRejected;
281 ASSERT_FALSE(promise.isEmpty());
283 ScriptState::Scope scope(scriptState());
284 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
288 isolate()->RunMicrotasks();
290 EXPECT_EQ("undefined", onFulfilled);
291 EXPECT_EQ(String(), onRejected);
294 TEST_F(ScriptPromiseResolverTest, rejectVoid)
296 RefPtr<ScriptPromiseResolver> resolver;
297 ScriptPromise promise;
299 ScriptState::Scope scope(scriptState());
300 resolver = ScriptPromiseResolver::create(scriptState());
301 promise = resolver->promise();
304 String onFulfilled, onRejected;
305 ASSERT_FALSE(promise.isEmpty());
307 ScriptState::Scope scope(scriptState());
308 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
312 isolate()->RunMicrotasks();
314 EXPECT_EQ(String(), onFulfilled);
315 EXPECT_EQ("undefined", onRejected);