2 * Copyright (C) 2014 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "bindings/core/v8/ScriptPromise.h"
34 #include "bindings/core/v8/ScriptFunction.h"
35 #include "bindings/core/v8/ScriptValue.h"
36 #include "bindings/core/v8/V8Binding.h"
37 #include "core/dom/DOMException.h"
38 #include "core/dom/ExceptionCode.h"
40 #include <gtest/gtest.h>
47 void callback(const v8::FunctionCallbackInfo<v8::Value>& info) { }
49 class Function : public ScriptFunction {
51 static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, String* value)
53 Function* self = new Function(scriptState, value);
54 return self->bindToV8Function();
58 Function(ScriptState* scriptState, String* value)
59 : ScriptFunction(scriptState)
64 virtual ScriptValue call(ScriptValue value) override
66 ASSERT(!value.isEmpty());
67 *m_value = toCoreString(value.v8Value()->ToString());
74 class ScriptPromiseTest : public testing::Test {
77 : m_scope(v8::Isolate::GetCurrent())
83 // FIXME: We put this statement here to clear an exception from the isolate.
84 createClosure(callback, v8::Undefined(m_scope.isolate()), m_scope.isolate());
86 // Execute all pending microtasks
87 isolate()->RunMicrotasks();
90 ScriptState* scriptState() const { return m_scope.scriptState(); }
91 v8::Isolate* isolate() const { return m_scope.isolate(); }
94 typedef ScriptPromise::InternalResolver Resolver;
95 V8TestingScope m_scope;
98 TEST_F(ScriptPromiseTest, constructFromNonPromise)
100 v8::TryCatch trycatch;
101 ScriptPromise promise(scriptState(), v8::Undefined(isolate()));
102 ASSERT_TRUE(trycatch.HasCaught());
103 ASSERT_TRUE(promise.isEmpty());
106 TEST_F(ScriptPromiseTest, thenResolve)
108 Resolver resolver(scriptState());
109 ScriptPromise promise = resolver.promise();
110 String onFulfilled, onRejected;
111 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
113 ASSERT_FALSE(promise.isEmpty());
114 EXPECT_EQ(String(), onFulfilled);
115 EXPECT_EQ(String(), onRejected);
117 isolate()->RunMicrotasks();
118 resolver.resolve(v8String(isolate(), "hello"));
120 EXPECT_EQ(String(), onFulfilled);
121 EXPECT_EQ(String(), onRejected);
123 isolate()->RunMicrotasks();
125 EXPECT_EQ("hello", onFulfilled);
126 EXPECT_EQ(String(), onRejected);
129 TEST_F(ScriptPromiseTest, resolveThen)
131 Resolver resolver(scriptState());
132 ScriptPromise promise = resolver.promise();
133 String onFulfilled, onRejected;
134 resolver.resolve(v8String(isolate(), "hello"));
135 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
137 ASSERT_FALSE(promise.isEmpty());
138 EXPECT_EQ(String(), onFulfilled);
139 EXPECT_EQ(String(), onRejected);
141 isolate()->RunMicrotasks();
143 EXPECT_EQ("hello", onFulfilled);
144 EXPECT_EQ(String(), onRejected);
147 TEST_F(ScriptPromiseTest, thenReject)
149 Resolver resolver(scriptState());
150 ScriptPromise promise = resolver.promise();
151 String onFulfilled, onRejected;
152 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
154 ASSERT_FALSE(promise.isEmpty());
155 EXPECT_EQ(String(), onFulfilled);
156 EXPECT_EQ(String(), onRejected);
158 isolate()->RunMicrotasks();
159 resolver.reject(v8String(isolate(), "hello"));
161 EXPECT_EQ(String(), onFulfilled);
162 EXPECT_EQ(String(), onRejected);
164 isolate()->RunMicrotasks();
166 EXPECT_EQ(String(), onFulfilled);
167 EXPECT_EQ("hello", onRejected);
170 TEST_F(ScriptPromiseTest, rejectThen)
172 Resolver resolver(scriptState());
173 ScriptPromise promise = resolver.promise();
174 String onFulfilled, onRejected;
175 resolver.reject(v8String(isolate(), "hello"));
176 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
178 ASSERT_FALSE(promise.isEmpty());
179 EXPECT_EQ(String(), onFulfilled);
180 EXPECT_EQ(String(), onRejected);
182 isolate()->RunMicrotasks();
184 EXPECT_EQ(String(), onFulfilled);
185 EXPECT_EQ("hello", onRejected);
188 TEST_F(ScriptPromiseTest, castPromise)
190 ScriptPromise promise = Resolver(scriptState()).promise();
191 ScriptPromise newPromise = ScriptPromise::cast(scriptState(), promise.v8Value());
193 ASSERT_FALSE(promise.isEmpty());
194 EXPECT_EQ(promise.v8Value(), newPromise.v8Value());
197 TEST_F(ScriptPromiseTest, castNonPromise)
199 String onFulfilled1, onFulfilled2, onRejected1, onRejected2;
201 ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello"));
202 ScriptPromise promise1 = ScriptPromise::cast(scriptState(), ScriptValue(value));
203 ScriptPromise promise2 = ScriptPromise::cast(scriptState(), ScriptValue(value));
204 promise1.then(Function::createFunction(scriptState(), &onFulfilled1), Function::createFunction(scriptState(), &onRejected1));
205 promise2.then(Function::createFunction(scriptState(), &onFulfilled2), Function::createFunction(scriptState(), &onRejected2));
207 ASSERT_FALSE(promise1.isEmpty());
208 ASSERT_FALSE(promise2.isEmpty());
209 EXPECT_NE(promise1.v8Value(), promise2.v8Value());
211 ASSERT_TRUE(promise1.v8Value()->IsPromise());
212 ASSERT_TRUE(promise2.v8Value()->IsPromise());
214 EXPECT_EQ(String(), onFulfilled1);
215 EXPECT_EQ(String(), onFulfilled2);
216 EXPECT_EQ(String(), onRejected1);
217 EXPECT_EQ(String(), onRejected2);
219 isolate()->RunMicrotasks();
221 EXPECT_EQ("hello", onFulfilled1);
222 EXPECT_EQ("hello", onFulfilled2);
223 EXPECT_EQ(String(), onRejected1);
224 EXPECT_EQ(String(), onRejected2);
227 TEST_F(ScriptPromiseTest, reject)
229 String onFulfilled, onRejected;
231 ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello"));
232 ScriptPromise promise = ScriptPromise::reject(scriptState(), ScriptValue(value));
233 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
235 ASSERT_FALSE(promise.isEmpty());
236 ASSERT_TRUE(promise.v8Value()->IsPromise());
238 EXPECT_EQ(String(), onFulfilled);
239 EXPECT_EQ(String(), onRejected);
241 isolate()->RunMicrotasks();
243 EXPECT_EQ(String(), onFulfilled);
244 EXPECT_EQ("hello", onRejected);
247 TEST_F(ScriptPromiseTest, rejectWithExceptionState)
249 String onFulfilled, onRejected;
250 ScriptPromise promise = ScriptPromise::rejectWithDOMException(scriptState(), DOMException::create(SyntaxError, "some syntax error"));
251 promise.then(Function::createFunction(scriptState(), &onFulfilled), Function::createFunction(scriptState(), &onRejected));
253 ASSERT_FALSE(promise.isEmpty());
254 EXPECT_EQ(String(), onFulfilled);
255 EXPECT_EQ(String(), onRejected);
257 isolate()->RunMicrotasks();
259 EXPECT_EQ(String(), onFulfilled);
260 EXPECT_EQ("SyntaxError: some syntax error", onRejected);