OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "bindings/core/v8/ScriptPromiseProperty.h" | 5 #include "bindings/core/v8/ScriptPromiseProperty.h" |
6 | 6 |
7 #include "bindings/core/v8/DOMWrapperWorld.h" | 7 #include "bindings/core/v8/DOMWrapperWorld.h" |
8 #include "bindings/core/v8/ScriptFunction.h" | 8 #include "bindings/core/v8/ScriptFunction.h" |
9 #include "bindings/core/v8/ScriptPromise.h" | 9 #include "bindings/core/v8/ScriptPromise.h" |
10 #include "bindings/core/v8/ScriptState.h" | 10 #include "bindings/core/v8/ScriptState.h" |
11 #include "bindings/core/v8/ScriptValue.h" | 11 #include "bindings/core/v8/ScriptValue.h" |
12 #include "bindings/core/v8/V8Binding.h" | 12 #include "bindings/core/v8/V8Binding.h" |
13 #include "bindings/core/v8/V8BindingForTesting.h" | 13 #include "bindings/core/v8/V8BindingForTesting.h" |
14 #include "bindings/core/v8/V8GCController.h" | 14 #include "bindings/core/v8/V8GCController.h" |
15 #include "core/dom/Document.h" | 15 #include "core/dom/Document.h" |
16 #include "core/testing/DummyPageHolder.h" | 16 #include "core/testing/DummyPageHolder.h" |
17 #include "core/testing/GCObservation.h" | 17 #include "core/testing/GCObservation.h" |
18 #include "core/testing/GarbageCollectedScriptWrappable.h" | 18 #include "core/testing/GarbageCollectedScriptWrappable.h" |
19 #include "core/testing/RefCountedScriptWrappable.h" | |
20 #include "platform/heap/Handle.h" | 19 #include "platform/heap/Handle.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "wtf/OwnPtr.h" | 21 #include "wtf/OwnPtr.h" |
23 #include "wtf/PassOwnPtr.h" | 22 #include "wtf/PassOwnPtr.h" |
24 #include "wtf/PassRefPtr.h" | 23 #include "wtf/PassRefPtr.h" |
25 #include "wtf/RefPtr.h" | 24 #include "wtf/RefPtr.h" |
26 #include <v8.h> | 25 #include <v8.h> |
27 | 26 |
28 using namespace blink; | 27 using namespace blink; |
29 | 28 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 DEFINE_INLINE_VIRTUAL_TRACE() | 91 DEFINE_INLINE_VIRTUAL_TRACE() |
93 { | 92 { |
94 GarbageCollectedScriptWrappable::trace(visitor); | 93 GarbageCollectedScriptWrappable::trace(visitor); |
95 visitor->trace(m_property); | 94 visitor->trace(m_property); |
96 } | 95 } |
97 | 96 |
98 private: | 97 private: |
99 Member<Property> m_property; | 98 Member<Property> m_property; |
100 }; | 99 }; |
101 | 100 |
102 class RefCountedHolder : public RefCountedScriptWrappable { | |
103 public: | |
104 // Do not resolve or reject the property with the holder itself. It leads | |
105 // to a leak. | |
106 typedef ScriptPromiseProperty<RefCountedScriptWrappable*, RefPtr<RefCountedS
criptWrappable>, RefPtr<RefCountedScriptWrappable>> Property; | |
107 static PassRefPtr<RefCountedHolder> create(ExecutionContext* executionContex
t) | |
108 { | |
109 return adoptRef(new RefCountedHolder(executionContext)); | |
110 } | |
111 Property* getProperty() { return m_property; } | |
112 RefCountedScriptWrappable* toRefCountedScriptWrappable() { return this; } | |
113 | |
114 private: | |
115 RefCountedHolder(ExecutionContext* executionContext) | |
116 : RefCountedScriptWrappable("holder") | |
117 , m_property(new Property(executionContext, toRefCountedScriptWrappable(
), Property::Ready)) { } | |
118 | |
119 Persistent<Property> m_property; | |
120 }; | |
121 | |
122 class ScriptPromisePropertyTestBase { | 101 class ScriptPromisePropertyTestBase { |
123 public: | 102 public: |
124 ScriptPromisePropertyTestBase() | 103 ScriptPromisePropertyTestBase() |
125 : m_page(DummyPageHolder::create(IntSize(1, 1))) | 104 : m_page(DummyPageHolder::create(IntSize(1, 1))) |
126 { | 105 { |
127 v8::HandleScope handleScope(isolate()); | 106 v8::HandleScope handleScope(isolate()); |
128 m_otherScriptState = ScriptStateForTesting::create(v8::Context::New(isol
ate()), DOMWrapperWorld::ensureIsolatedWorld(isolate(), 1, -1)); | 107 m_otherScriptState = ScriptStateForTesting::create(v8::Context::New(isol
ate()), DOMWrapperWorld::ensureIsolatedWorld(isolate(), 1, -1)); |
129 } | 108 } |
130 | 109 |
131 virtual ~ScriptPromisePropertyTestBase() | 110 virtual ~ScriptPromisePropertyTestBase() |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 | 386 |
408 v8::MicrotasksScope::PerformCheckpoint(isolate()); | 387 v8::MicrotasksScope::PerformCheckpoint(isolate()); |
409 EXPECT_EQ(1u, nOldResolveCalls); | 388 EXPECT_EQ(1u, nOldResolveCalls); |
410 EXPECT_EQ(1u, nNewRejectCalls); | 389 EXPECT_EQ(1u, nNewRejectCalls); |
411 EXPECT_NE(oldPromise, newPromise); | 390 EXPECT_NE(oldPromise, newPromise); |
412 EXPECT_EQ(wrap(mainWorld(), oldValue), oldActual); | 391 EXPECT_EQ(wrap(mainWorld(), oldValue), oldActual); |
413 EXPECT_EQ(wrap(mainWorld(), newValue), newActual); | 392 EXPECT_EQ(wrap(mainWorld(), newValue), newActual); |
414 EXPECT_NE(oldActual, newActual); | 393 EXPECT_NE(oldActual, newActual); |
415 } | 394 } |
416 | 395 |
417 // Tests that ScriptPromiseProperty works with a ref-counted holder. | |
418 class ScriptPromisePropertyRefCountedTest : public ScriptPromisePropertyTestBase
, public ::testing::Test { | |
419 public: | |
420 typedef RefCountedHolder::Property Property; | |
421 | |
422 ScriptPromisePropertyRefCountedTest() | |
423 : m_holder(RefCountedHolder::create(&document())) | |
424 { | |
425 } | |
426 | |
427 RefCountedHolder* holder() { return m_holder.get(); } | |
428 Property* getProperty() { return m_holder->getProperty(); } | |
429 | |
430 private: | |
431 RefPtr<RefCountedHolder> m_holder; | |
432 }; | |
433 | |
434 TEST_F(ScriptPromisePropertyRefCountedTest, Resolve) | |
435 { | |
436 ScriptValue actual; | |
437 size_t nResolveCalls = 0; | |
438 | |
439 { | |
440 ScriptState::Scope scope(mainScriptState()); | |
441 getProperty()->promise(DOMWrapperWorld::mainWorld()).then(stub(currentSc
riptState(), actual, nResolveCalls), notReached(currentScriptState())); | |
442 } | |
443 | |
444 RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create(
"value"); | |
445 getProperty()->resolve(value.get()); | |
446 EXPECT_EQ(Property::Resolved, getProperty()->getState()); | |
447 | |
448 v8::MicrotasksScope::PerformCheckpoint(isolate()); | |
449 EXPECT_EQ(1u, nResolveCalls); | |
450 EXPECT_EQ(wrap(mainWorld(), value), actual); | |
451 } | |
452 | |
453 TEST_F(ScriptPromisePropertyRefCountedTest, Reject) | |
454 { | |
455 ScriptValue actual; | |
456 size_t nRejectCalls = 0; | |
457 | |
458 { | |
459 ScriptState::Scope scope(mainScriptState()); | |
460 getProperty()->promise(DOMWrapperWorld::mainWorld()).then(notReached(cur
rentScriptState()), stub(currentScriptState(), actual, nRejectCalls)); | |
461 } | |
462 | |
463 RefPtr<RefCountedScriptWrappable> reason = RefCountedScriptWrappable::create
("reason"); | |
464 getProperty()->reject(reason); | |
465 EXPECT_EQ(Property::Rejected, getProperty()->getState()); | |
466 | |
467 v8::MicrotasksScope::PerformCheckpoint(isolate()); | |
468 EXPECT_EQ(1u, nRejectCalls); | |
469 EXPECT_EQ(wrap(mainWorld(), reason), actual); | |
470 } | |
471 | |
472 TEST_F(ScriptPromisePropertyRefCountedTest, ReSolveAndReset) | |
473 { | |
474 RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create(
"value"); | |
475 | |
476 { | |
477 ScriptState::Scope scope(mainScriptState()); | |
478 getProperty()->resolve(value); | |
479 } | |
480 | |
481 EXPECT_EQ(2, value->refCount()); | |
482 getProperty()->reset(); | |
483 EXPECT_EQ(1, value->refCount()); | |
484 } | |
485 | |
486 TEST_F(ScriptPromisePropertyRefCountedTest, RejectAndReset) | |
487 { | |
488 RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create(
"value"); | |
489 | |
490 { | |
491 ScriptState::Scope scope(mainScriptState()); | |
492 getProperty()->reject(value.get()); | |
493 } | |
494 | |
495 EXPECT_EQ(2, value->refCount()); | |
496 getProperty()->reset(); | |
497 EXPECT_EQ(1, value->refCount()); | |
498 } | |
499 | |
500 // Tests that ScriptPromiseProperty works with a non ScriptWrappable resolution | 396 // Tests that ScriptPromiseProperty works with a non ScriptWrappable resolution |
501 // target. | 397 // target. |
502 class ScriptPromisePropertyNonScriptWrappableResolutionTargetTest : public Scrip
tPromisePropertyTestBase, public ::testing::Test { | 398 class ScriptPromisePropertyNonScriptWrappableResolutionTargetTest : public Scrip
tPromisePropertyTestBase, public ::testing::Test { |
503 public: | 399 public: |
504 template <typename T> | 400 template <typename T> |
505 void test(const T& value, const char* expected, const char* file, size_t lin
e) | 401 void test(const T& value, const char* expected, const char* file, size_t lin
e) |
506 { | 402 { |
507 typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, T
, ToV8UndefinedGenerator> Property; | 403 typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, T
, ToV8UndefinedGenerator> Property; |
508 Property* property = new Property(&document(), new GarbageCollectedScrip
tWrappable("holder"), Property::Ready); | 404 Property* property = new Property(&document(), new GarbageCollectedScrip
tWrappable("holder"), Property::Ready); |
509 size_t nResolveCalls = 0; | 405 size_t nResolveCalls = 0; |
(...skipping 25 matching lines...) Expand all Loading... |
535 { | 431 { |
536 test(String("hello"), "hello", __FILE__, __LINE__); | 432 test(String("hello"), "hello", __FILE__, __LINE__); |
537 } | 433 } |
538 | 434 |
539 TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithI
nteger) | 435 TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithI
nteger) |
540 { | 436 { |
541 test(-1, "-1", __FILE__, __LINE__); | 437 test(-1, "-1", __FILE__, __LINE__); |
542 } | 438 } |
543 | 439 |
544 } // namespace | 440 } // namespace |
OLD | NEW |