| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "bindings/v8/ScriptPromiseResolver.h" | 32 #include "bindings/v8/ScriptPromiseResolver.h" |
| 33 | 33 |
| 34 #include "RuntimeEnabledFeatures.h" | |
| 35 #include "bindings/v8/DOMWrapperWorld.h" | |
| 36 #include "bindings/v8/ScriptPromise.h" | 34 #include "bindings/v8/ScriptPromise.h" |
| 37 #include "bindings/v8/V8Binding.h" | 35 #include "bindings/v8/V8Binding.h" |
| 38 #include "bindings/v8/custom/V8PromiseCustom.h" | |
| 39 | 36 |
| 40 #include <gtest/gtest.h> | 37 #include <gtest/gtest.h> |
| 41 #include <v8.h> | 38 #include <v8.h> |
| 42 | 39 |
| 43 namespace WebCore { | 40 namespace WebCore { |
| 44 | 41 |
| 45 namespace { | 42 namespace { |
| 46 | 43 |
| 44 class Function : public ScriptFunction { |
| 45 public: |
| 46 static PassOwnPtr<Function> create(v8::Isolate* isolate, String* value) |
| 47 { |
| 48 return adoptPtr(new Function(isolate, value)); |
| 49 } |
| 50 |
| 51 virtual ScriptValue call(ScriptValue value) OVERRIDE |
| 52 { |
| 53 ASSERT(!value.isEmpty()); |
| 54 *m_value = toCoreString(value.v8Value()->ToString()); |
| 55 return value; |
| 56 } |
| 57 |
| 58 private: |
| 59 Function(v8::Isolate* isolate, String* value) : ScriptFunction(isolate), m_v
alue(value) { } |
| 60 |
| 61 String* m_value; |
| 62 }; |
| 63 |
| 47 class ScriptPromiseResolverTest : public testing::Test { | 64 class ScriptPromiseResolverTest : public testing::Test { |
| 48 public: | 65 public: |
| 49 ScriptPromiseResolverTest() | 66 ScriptPromiseResolverTest() |
| 50 : m_isolate(v8::Isolate::GetCurrent()) | 67 : m_scope(V8ExecutionScope::create(v8::Isolate::GetCurrent())) |
| 51 { | 68 { |
| 69 m_resolver = ScriptPromiseResolver::create(m_scope->scriptState()); |
| 52 } | 70 } |
| 53 | 71 |
| 54 void SetUp() | 72 virtual ~ScriptPromiseResolverTest() |
| 55 { | 73 { |
| 56 m_scope = V8ExecutionScope::create(m_isolate); | 74 // Run all pending microtasks here. |
| 57 m_resolver = ScriptPromiseResolver::create(m_scope->scriptState()); | 75 isolate()->RunMicrotasks(); |
| 58 m_promise = m_resolver->promise(); | |
| 59 } | 76 } |
| 60 | 77 |
| 61 void TearDown() | 78 v8::Isolate* isolate() { return m_scope->isolate(); } |
| 62 { | |
| 63 m_resolver = nullptr; | |
| 64 m_promise.clear(); | |
| 65 m_scope.clear(); | |
| 66 } | |
| 67 | |
| 68 V8PromiseCustom::PromiseState state() | |
| 69 { | |
| 70 return V8PromiseCustom::getState(V8PromiseCustom::getInternal(promise())
); | |
| 71 } | |
| 72 | |
| 73 v8::Local<v8::Value> result() | |
| 74 { | |
| 75 return V8PromiseCustom::getInternal(promise())->GetInternalField(V8Promi
seCustom::InternalResultIndex); | |
| 76 } | |
| 77 | |
| 78 v8::Local<v8::Object> promise() | |
| 79 { | |
| 80 ASSERT(!m_promise.isEmpty()); | |
| 81 return m_promise.v8Value().As<v8::Object>(); | |
| 82 } | |
| 83 | 79 |
| 84 protected: | 80 protected: |
| 85 v8::Isolate* m_isolate; | |
| 86 RefPtr<ScriptPromiseResolver> m_resolver; | 81 RefPtr<ScriptPromiseResolver> m_resolver; |
| 87 ScriptPromise m_promise; | |
| 88 private: | |
| 89 OwnPtr<V8ExecutionScope> m_scope; | 82 OwnPtr<V8ExecutionScope> m_scope; |
| 90 }; | 83 }; |
| 91 | 84 |
| 92 TEST_F(ScriptPromiseResolverTest, initialState) | 85 TEST_F(ScriptPromiseResolverTest, initialState) |
| 93 { | 86 { |
| 94 if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) | 87 ScriptPromise promise = m_resolver->promise(); |
| 95 return; | 88 ASSERT_FALSE(promise.isEmpty()); |
| 96 EXPECT_EQ(V8PromiseCustom::Pending, state()); | 89 String onFulfilled, onRejected; |
| 97 EXPECT_TRUE(result()->IsUndefined()); | 90 promise.then(Function::create(isolate(), &onFulfilled), Function::create(iso
late(), &onRejected)); |
| 91 |
| 92 EXPECT_EQ(String(), onFulfilled); |
| 93 EXPECT_EQ(String(), onRejected); |
| 94 |
| 95 isolate()->RunMicrotasks(); |
| 96 |
| 97 EXPECT_EQ(String(), onFulfilled); |
| 98 EXPECT_EQ(String(), onRejected); |
| 98 } | 99 } |
| 99 | 100 |
| 100 TEST_F(ScriptPromiseResolverTest, resolve) | 101 TEST_F(ScriptPromiseResolverTest, resolve) |
| 101 { | 102 { |
| 102 if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) | 103 ScriptPromise promise = m_resolver->promise(); |
| 103 return; | 104 ASSERT_FALSE(promise.isEmpty()); |
| 104 EXPECT_EQ(V8PromiseCustom::Pending, state()); | 105 String onFulfilled, onRejected; |
| 105 EXPECT_TRUE(result()->IsUndefined()); | 106 promise.then(Function::create(isolate(), &onFulfilled), Function::create(iso
late(), &onRejected)); |
| 106 | 107 |
| 107 m_resolver->resolve(ScriptValue(ScriptState::current(m_isolate), v8::Integer
::New(m_isolate, 3))); | 108 EXPECT_EQ(String(), onFulfilled); |
| 109 EXPECT_EQ(String(), onRejected); |
| 108 | 110 |
| 109 EXPECT_EQ(V8PromiseCustom::Fulfilled, state()); | 111 m_resolver->resolve("hello"); |
| 110 ASSERT_TRUE(result()->IsNumber()); | 112 EXPECT_TRUE(m_resolver->promise().isEmpty()); |
| 111 EXPECT_EQ(3, result().As<v8::Integer>()->Value()); | 113 isolate()->RunMicrotasks(); |
| 114 |
| 115 EXPECT_EQ("hello", onFulfilled); |
| 116 EXPECT_EQ(String(), onRejected); |
| 112 } | 117 } |
| 113 | 118 |
| 114 TEST_F(ScriptPromiseResolverTest, reject) | 119 TEST_F(ScriptPromiseResolverTest, reject) |
| 115 { | 120 { |
| 116 if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) | 121 ScriptPromise promise = m_resolver->promise(); |
| 117 return; | 122 ASSERT_FALSE(promise.isEmpty()); |
| 118 EXPECT_EQ(V8PromiseCustom::Pending, state()); | 123 String onFulfilled, onRejected; |
| 119 EXPECT_TRUE(result()->IsUndefined()); | 124 promise.then(Function::create(isolate(), &onFulfilled), Function::create(iso
late(), &onRejected)); |
| 120 | 125 |
| 121 m_resolver->reject(ScriptValue(ScriptState::current(m_isolate), v8::Integer:
:New(m_isolate, 3))); | 126 EXPECT_EQ(String(), onFulfilled); |
| 127 EXPECT_EQ(String(), onRejected); |
| 122 | 128 |
| 123 EXPECT_EQ(V8PromiseCustom::Rejected, state()); | 129 m_resolver->reject("hello"); |
| 124 ASSERT_TRUE(result()->IsNumber()); | 130 EXPECT_TRUE(m_resolver->promise().isEmpty()); |
| 125 EXPECT_EQ(3, result().As<v8::Integer>()->Value()); | 131 isolate()->RunMicrotasks(); |
| 132 |
| 133 EXPECT_EQ(String(), onFulfilled); |
| 134 EXPECT_EQ("hello", onRejected); |
| 126 } | 135 } |
| 127 | 136 |
| 128 TEST_F(ScriptPromiseResolverTest, resolveOverResolve) | 137 TEST_F(ScriptPromiseResolverTest, resolveOverResolve) |
| 129 { | 138 { |
| 130 if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) | 139 ScriptPromise promise = m_resolver->promise(); |
| 131 return; | 140 ASSERT_FALSE(promise.isEmpty()); |
| 132 EXPECT_EQ(V8PromiseCustom::Pending, state()); | 141 String onFulfilled, onRejected; |
| 133 EXPECT_TRUE(result()->IsUndefined()); | 142 promise.then(Function::create(isolate(), &onFulfilled), Function::create(iso
late(), &onRejected)); |
| 134 | 143 |
| 135 m_resolver->resolve(ScriptValue(ScriptState::current(m_isolate), v8::Integer
::New(m_isolate, 3))); | 144 EXPECT_EQ(String(), onFulfilled); |
| 145 EXPECT_EQ(String(), onRejected); |
| 136 | 146 |
| 137 EXPECT_EQ(V8PromiseCustom::Fulfilled, state()); | 147 m_resolver->resolve("hello"); |
| 138 ASSERT_TRUE(result()->IsNumber()); | 148 EXPECT_TRUE(m_resolver->promise().isEmpty()); |
| 139 EXPECT_EQ(3, result().As<v8::Integer>()->Value()); | 149 isolate()->RunMicrotasks(); |
| 140 | 150 |
| 141 m_resolver->resolve(ScriptValue(ScriptState::current(m_isolate), v8::Integer
::New(m_isolate, 4))); | 151 EXPECT_EQ("hello", onFulfilled); |
| 142 EXPECT_EQ(V8PromiseCustom::Fulfilled, state()); | 152 EXPECT_EQ(String(), onRejected); |
| 143 ASSERT_TRUE(result()->IsNumber()); | 153 |
| 144 EXPECT_EQ(3, result().As<v8::Integer>()->Value()); | 154 m_resolver->resolve("world"); |
| 155 isolate()->RunMicrotasks(); |
| 156 |
| 157 EXPECT_EQ("hello", onFulfilled); |
| 158 EXPECT_EQ(String(), onRejected); |
| 145 } | 159 } |
| 146 | 160 |
| 147 TEST_F(ScriptPromiseResolverTest, rejectOverResolve) | 161 TEST_F(ScriptPromiseResolverTest, rejectOverResolve) |
| 148 { | 162 { |
| 149 if (RuntimeEnabledFeatures::scriptPromiseOnV8PromiseEnabled()) | 163 ScriptPromise promise = m_resolver->promise(); |
| 150 return; | 164 ASSERT_FALSE(promise.isEmpty()); |
| 151 EXPECT_EQ(V8PromiseCustom::Pending, state()); | 165 String onFulfilled, onRejected; |
| 152 EXPECT_TRUE(result()->IsUndefined()); | 166 promise.then(Function::create(isolate(), &onFulfilled), Function::create(iso
late(), &onRejected)); |
| 153 | 167 |
| 154 m_resolver->resolve(ScriptValue(ScriptState::current(m_isolate), v8::Integer
::New(m_isolate, 3))); | 168 EXPECT_EQ(String(), onFulfilled); |
| 169 EXPECT_EQ(String(), onRejected); |
| 155 | 170 |
| 156 EXPECT_EQ(V8PromiseCustom::Fulfilled, state()); | 171 m_resolver->resolve("hello"); |
| 157 ASSERT_TRUE(result()->IsNumber()); | 172 EXPECT_TRUE(m_resolver->promise().isEmpty()); |
| 158 EXPECT_EQ(3, result().As<v8::Integer>()->Value()); | 173 isolate()->RunMicrotasks(); |
| 159 | 174 |
| 160 m_resolver->reject(ScriptValue(ScriptState::current(m_isolate), v8::Integer:
:New(m_isolate, 4))); | 175 EXPECT_EQ("hello", onFulfilled); |
| 161 EXPECT_EQ(V8PromiseCustom::Fulfilled, state()); | 176 EXPECT_EQ(String(), onRejected); |
| 162 ASSERT_TRUE(result()->IsNumber()); | 177 |
| 163 EXPECT_EQ(3, result().As<v8::Integer>()->Value()); | 178 m_resolver->reject("world"); |
| 179 isolate()->RunMicrotasks(); |
| 180 |
| 181 EXPECT_EQ("hello", onFulfilled); |
| 182 EXPECT_EQ(String(), onRejected); |
| 164 } | 183 } |
| 165 | 184 |
| 166 } // namespace | 185 } // namespace |
| 167 | 186 |
| 168 } // namespace WebCore | 187 } // namespace WebCore |
| OLD | NEW |