1197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// found in the LICENSE file.
4197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
5197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "config.h"
6197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptPromiseProperty.h"
7197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
8197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/DOMWrapperWorld.h"
9197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptFunction.h"
10197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptPromise.h"
11197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptState.h"
12197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptValue.h"
13197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Binding.h"
14197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8GCController.h"
15197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Document.h"
16197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/testing/DummyPageHolder.h"
17197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/testing/GCObservation.h"
18c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/testing/GarbageCollectedScriptWrappable.h"
19c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/testing/RefCountedScriptWrappable.h"
20c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "platform/heap/Handle.h"
21197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/OwnPtr.h"
22197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/PassOwnPtr.h"
23197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/PassRefPtr.h"
24197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/RefPtr.h"
25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include <gtest/gtest.h>
26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include <v8.h>
27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
28c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink;
29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdochnamespace {
31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
32197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass NotReached : public ScriptFunction {
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic:
347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Function> createFunction(ScriptState* scriptState)
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        NotReached* self = new NotReached(scriptState);
377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return self->bindToV8Function();
387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
40197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate:
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    explicit NotReached(ScriptState* scriptState)
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        : ScriptFunction(scriptState)
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual ScriptValue call(ScriptValue) OVERRIDE;
47197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
48197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
49197021e6b966cfb06891637935ef33fff06433d1Ben MurdochScriptValue NotReached::call(ScriptValue)
50197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
51197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_TRUE(false) << "'Unreachable' code was reached";
52197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return ScriptValue();
53197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
55197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass StubFunction : public ScriptFunction {
56197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic:
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, ScriptValue& value, size_t& callCount)
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        StubFunction* self = new StubFunction(scriptState, value, callCount);
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return self->bindToV8Function();
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
62197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
63197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate:
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    StubFunction(ScriptState* scriptState, ScriptValue& value, size_t& callCount)
657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        : ScriptFunction(scriptState)
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        , m_value(value)
677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        , m_callCount(callCount)
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual ScriptValue call(ScriptValue arg) OVERRIDE
727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_value = arg;
747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_callCount++;
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return ScriptValue();
767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ScriptValue& m_value;
79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t& m_callCount;
80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class GarbageCollectedHolder : public GarbageCollectedScriptWrappable {
83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, Member<GarbageCollectedScriptWrappable>, Member<GarbageCollectedScriptWrappable> > Property;
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedHolder(ExecutionContext* executionContext)
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : GarbageCollectedScriptWrappable("holder")
87c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        , m_property(new Property(executionContext, toGarbageCollectedScriptWrappable(), Property::Ready)) { }
88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Property* property() { return m_property; }
90c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedScriptWrappable* toGarbageCollectedScriptWrappable() { return this; }
91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void trace(Visitor *visitor) OVERRIDE
93c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
94c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        GarbageCollectedScriptWrappable::trace(visitor);
95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        visitor->trace(m_property);
96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Member<Property> m_property;
100c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class RefCountedHolder : public RefCountedScriptWrappable {
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
104e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // Do not resolve or reject the property with the holder itself. It leads
105e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // to a leak.
106e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    typedef ScriptPromiseProperty<RefCountedScriptWrappable*, RefPtr<RefCountedScriptWrappable>, RefPtr<RefCountedScriptWrappable> > Property;
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static PassRefPtr<RefCountedHolder> create(ExecutionContext* executionContext)
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return adoptRef(new RefCountedHolder(executionContext));
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Property* property() { return m_property; }
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefCountedScriptWrappable* toRefCountedScriptWrappable() { return this; }
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefCountedHolder(ExecutionContext* executionContext)
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : RefCountedScriptWrappable("holder")
117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        , m_property(new Property(executionContext, toRefCountedScriptWrappable(), Property::Ready)) { }
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Persistent<Property> m_property;
120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class ScriptPromisePropertyTestBase {
123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromisePropertyTestBase()
125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        : m_page(DummyPageHolder::create(IntSize(1, 1)))
126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        v8::HandleScope handleScope(isolate());
128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_otherScriptState = ScriptStateForTesting::create(v8::Context::New(isolate()), DOMWrapperWorld::create(1));
129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual ~ScriptPromisePropertyTestBase()
132c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_page.clear();
134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        gc();
135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Heap::collectAllGarbage();
136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
138197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Document& document() { return m_page->document(); }
139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::Isolate* isolate() { return toIsolate(&document()); }
140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptState* mainScriptState() { return ScriptState::forMainWorld(document().frame()); }
141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    DOMWrapperWorld& mainWorld() { return mainScriptState()->world(); }
142c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptState* otherScriptState() { return m_otherScriptState.get(); }
143c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    DOMWrapperWorld& otherWorld() { return m_otherScriptState->world(); }
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ScriptState* currentScriptState() { return ScriptState::current(isolate()); }
145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
146c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void destroyContext()
147197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
148197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_page.clear();
149c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_otherScriptState.clear();
150197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        gc();
151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Heap::collectGarbage(ThreadState::HeapPointersOnStack);
152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    void gc() { V8GCController::collectGarbage(v8::Isolate::GetCurrent()); }
155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    v8::Handle<v8::Function> notReached(ScriptState* scriptState) { return NotReached::createFunction(scriptState); }
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    v8::Handle<v8::Function> stub(ScriptState* scriptState, ScriptValue& value, size_t& callCount) { return StubFunction::createFunction(scriptState, value, callCount); }
158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
159c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    template <typename T>
160c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue wrap(DOMWrapperWorld& world, const T& value)
161c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
162c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        v8::HandleScope handleScope(isolate());
163c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState* scriptState = ScriptState::from(toV8Context(&document(), world));
164c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(scriptState);
165c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return ScriptValue(scriptState, V8ValueTraits<T>::toV8Value(value, scriptState->context()->Global(), isolate()));
166c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
167c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
168c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    OwnPtr<DummyPageHolder> m_page;
170c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtr<ScriptState> m_otherScriptState;
171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
172c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
173c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// This is the main test class.
174c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// If you want to examine a testcase independent of holder types, place the
175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// test on this class.
176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class ScriptPromisePropertyGarbageCollectedTest : public ScriptPromisePropertyTestBase, public ::testing::Test {
177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef GarbageCollectedHolder::Property Property;
179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromisePropertyGarbageCollectedTest()
181c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : m_holder(new GarbageCollectedHolder(&document()))
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
185c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedHolder* holder() { return m_holder; }
186c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Property* property() { return m_holder->property(); }
187c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise promise(DOMWrapperWorld& world) { return property()->promise(world); }
188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
189c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    virtual void destroyContext() OVERRIDE
190c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
191c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_holder = nullptr;
192c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptPromisePropertyTestBase::destroyContext();
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
194197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
195197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate:
196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Persistent<GarbageCollectedHolder> m_holder;
197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
198197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
199c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_IsStableObjectInMainWorld)
200197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
201c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise v = property()->promise(DOMWrapperWorld::mainWorld());
202c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise w = property()->promise(DOMWrapperWorld::mainWorld());
203197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(v, w);
204c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT_FALSE(v.isEmpty());
205c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
206c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
207c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(v.v8Value().As<v8::Object>()->CreationContext(), toV8Context(&document(), mainWorld()));
208c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Pending, property()->state());
210197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
212c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_IsStableObjectInVariousWorlds)
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
214c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise u = property()->promise(otherWorld());
215c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise v = property()->promise(DOMWrapperWorld::mainWorld());
216c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise w = property()->promise(DOMWrapperWorld::mainWorld());
217c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(mainScriptState(), otherScriptState());
218c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(&mainWorld(), &otherWorld());
219c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(u, v);
220c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(v, w);
221c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT_FALSE(u.isEmpty());
222c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT_FALSE(v.isEmpty());
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
224c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(otherScriptState());
225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(u.v8Value().As<v8::Object>()->CreationContext(), toV8Context(&document(), otherWorld()));
226c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
227c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
228c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
229c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        EXPECT_EQ(v.v8Value().As<v8::Object>()->CreationContext(), toV8Context(&document(), mainWorld()));
230c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
231c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Pending, property()->state());
232c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
233197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
234c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_IsStableObjectAfterSettling)
235c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
236c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise v = promise(DOMWrapperWorld::mainWorld());
237c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedScriptWrappable* value = new GarbageCollectedScriptWrappable("value");
238197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
239c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property()->resolve(value);
240c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Resolved, property()->state());
241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
242c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise w = promise(DOMWrapperWorld::mainWorld());
243197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(v, w);
244197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_FALSE(v.isEmpty());
245197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
246197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
247c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_DoesNotImpedeGarbageCollection)
248197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
249c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue holderWrapper = wrap(mainWorld(), holder()->toGarbageCollectedScriptWrappable());
250197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Persistent<GCObservation> observation;
252197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
253c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
254c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        observation = GCObservation::create(promise(DOMWrapperWorld::mainWorld()).v8Value());
255197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
256197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
257197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    gc();
258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_FALSE(observation->wasCollected());
259197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
260197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    holderWrapper.clear();
261197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    gc();
262197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_TRUE(observation->wasCollected());
263197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Pending, property()->state());
265197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
266197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
267c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Resolve_ResolvesScriptPromise)
268197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
269c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise promise = property()->promise(DOMWrapperWorld::mainWorld());
270c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise otherPromise = property()->promise(otherWorld());
271c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue actual, otherActual;
272197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t nResolveCalls = 0;
273c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t nOtherResolveCalls = 0;
274197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
275197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
276c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
2777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        promise.then(stub(currentScriptState(), actual, nResolveCalls), notReached(currentScriptState()));
278197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
280c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
281c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(otherScriptState());
2827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
283c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
284c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
285c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(promise, otherPromise);
286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
287c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedScriptWrappable* value = new GarbageCollectedScriptWrappable("value");
288c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property()->resolve(value);
289c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Resolved, property()->state());
290197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    isolate()->RunMicrotasks();
292197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(1u, nResolveCalls);
293c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nOtherResolveCalls);
294c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), value), actual);
295c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(actual, otherActual);
296c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(otherWorld(), value), otherActual);
297197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
298197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
299c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, ResolveAndGetPromiseOnOtherWorld)
300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
301c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise promise = property()->promise(DOMWrapperWorld::mainWorld());
302c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromise otherPromise = property()->promise(otherWorld());
303c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue actual, otherActual;
304c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t nResolveCalls = 0;
305c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t nOtherResolveCalls = 0;
306c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
307c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
308c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        promise.then(stub(currentScriptState(), actual, nResolveCalls), notReached(currentScriptState()));
310c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
311197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
312c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(promise, otherPromise);
313c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedScriptWrappable* value = new GarbageCollectedScriptWrappable("value");
314c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property()->resolve(value);
315c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Resolved, property()->state());
316c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
317c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    isolate()->RunMicrotasks();
318c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nResolveCalls);
319c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(0u, nOtherResolveCalls);
320197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
321c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
322c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(otherScriptState());
3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
324c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
325c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
326c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    isolate()->RunMicrotasks();
327c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nResolveCalls);
328c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nOtherResolveCalls);
329c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), value), actual);
330c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(actual, otherActual);
331c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(otherWorld(), value), otherActual);
332c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
333c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
334c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reject_RejectsScriptPromise)
335c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
336c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    GarbageCollectedScriptWrappable* reason = new GarbageCollectedScriptWrappable("reason");
337c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property()->reject(reason);
338c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Rejected, property()->state());
339c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
340c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue actual, otherActual;
341197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    size_t nRejectCalls = 0;
342c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t nOtherRejectCalls = 0;
343c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
344c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        property()->promise(DOMWrapperWorld::mainWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), actual, nRejectCalls));
346c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
347197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
348197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
349c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(otherScriptState());
3507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        property()->promise(otherWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), otherActual, nOtherRejectCalls));
351197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
352197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
353197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    isolate()->RunMicrotasks();
354197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EXPECT_EQ(1u, nRejectCalls);
355c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), reason), actual);
356c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nOtherRejectCalls);
357c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_NE(actual, otherActual);
358c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(otherWorld(), reason), otherActual);
359197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
360197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
361c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_DeadContext)
362197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
363c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Property* property = this->property();
364c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property->resolve(new GarbageCollectedScriptWrappable("value"));
365c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Resolved, property->state());
366197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
367197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    destroyContext();
368197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
369c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_TRUE(property->promise(DOMWrapperWorld::mainWorld()).isEmpty());
370197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
371197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
372c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Resolve_DeadContext)
373197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
374c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Property* property = this->property();
375197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
376197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
377c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
3787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        property->promise(DOMWrapperWorld::mainWorld()).then(notReached(currentScriptState()), notReached(currentScriptState()));
379197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
380197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
381197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    destroyContext();
382c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_TRUE(!property->executionContext() || property->executionContext()->activeDOMObjectsAreStopped());
383197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
384c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property->resolve(new GarbageCollectedScriptWrappable("value"));
385c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Pending, property->state());
386197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
387197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::Isolate::GetCurrent()->RunMicrotasks();
388197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
389197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
390e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset)
391e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
392e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ScriptPromise oldPromise, newPromise;
393e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ScriptValue oldActual, newActual;
394e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    GarbageCollectedScriptWrappable* oldValue = new GarbageCollectedScriptWrappable("old");
395e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    GarbageCollectedScriptWrappable* newValue = new GarbageCollectedScriptWrappable("new");
396e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    size_t nOldResolveCalls = 0;
397e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    size_t nNewRejectCalls = 0;
398e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
399e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    {
400e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
401e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        property()->resolve(oldValue);
402e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        oldPromise = property()->promise(mainWorld());
4037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        oldPromise.then(stub(currentScriptState(), oldActual, nOldResolveCalls), notReached(currentScriptState()));
404e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    }
405e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
406e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    property()->reset();
407e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
408e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    {
409e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
410e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        newPromise = property()->promise(mainWorld());
4117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        newPromise.then(notReached(currentScriptState()), stub(currentScriptState(), newActual, nNewRejectCalls));
412e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        property()->reject(newValue);
413e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    }
414e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
415e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(0u, nOldResolveCalls);
416e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(0u, nNewRejectCalls);
417e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
418e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    isolate()->RunMicrotasks();
419e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(1u, nOldResolveCalls);
420e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(1u, nNewRejectCalls);
421e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_NE(oldPromise, newPromise);
422e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), oldValue), oldActual);
423e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), newValue), newActual);
424e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_NE(oldActual, newActual);
425e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
426e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
427c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// Tests that ScriptPromiseProperty works with a ref-counted holder.
428c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class ScriptPromisePropertyRefCountedTest : public ScriptPromisePropertyTestBase, public ::testing::Test {
429c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
430c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    typedef RefCountedHolder::Property Property;
431c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
432c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptPromisePropertyRefCountedTest()
433c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        : m_holder(RefCountedHolder::create(&document()))
434c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
435c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
436c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
437c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefCountedHolder* holder() { return m_holder.get(); }
438c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Property* property() { return m_holder->property(); }
439c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
440c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)private:
441c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtr<RefCountedHolder> m_holder;
442c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
443c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
444c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyRefCountedTest, Resolve)
445c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
446c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue actual;
447c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t nResolveCalls = 0;
448c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
449c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
450c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
4517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        property()->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actual, nResolveCalls), notReached(currentScriptState()));
452c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
453c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
454c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create("value");
455c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    property()->resolve(value.get());
456c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Resolved, property()->state());
457c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
458c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    isolate()->RunMicrotasks();
459c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nResolveCalls);
460c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), value), actual);
461c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
462c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
463c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyRefCountedTest, Reject)
464c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
465c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ScriptValue actual;
466c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    size_t nRejectCalls = 0;
467c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
468c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
469c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
4707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        property()->promise(DOMWrapperWorld::mainWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), actual, nRejectCalls));
471c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
472c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
473c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtr<RefCountedScriptWrappable> reason = RefCountedScriptWrappable::create("reason");
474e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    property()->reject(reason);
475c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(Property::Rejected, property()->state());
476c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
477c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    isolate()->RunMicrotasks();
478c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(1u, nRejectCalls);
479c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    EXPECT_EQ(wrap(mainWorld(), reason), actual);
480c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
481c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
482e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)TEST_F(ScriptPromisePropertyRefCountedTest, ReSolveAndReset)
483e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
484e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create("value");
485e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
486e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    {
487e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
488e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        property()->resolve(value);
489e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    }
490e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
491e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(2, value->refCount());
492e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    property()->reset();
493e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(1, value->refCount());
494e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
495e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
496e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)TEST_F(ScriptPromisePropertyRefCountedTest, RejectAndReset)
497e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
498e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create("value");
499e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
500e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    {
501e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        ScriptState::Scope scope(mainScriptState());
502e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        property()->reject(value.get());
503e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    }
504e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
505e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(2, value->refCount());
506e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    property()->reset();
507e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    EXPECT_EQ(1, value->refCount());
508e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
509e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
510c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// Tests that ScriptPromiseProperty works with a non ScriptWrappable resolution
511c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// target.
512c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class ScriptPromisePropertyNonScriptWrappableResolutionTargetTest : public ScriptPromisePropertyTestBase, public ::testing::Test {
513c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public:
514c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    template <typename T>
515c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void test(const T& value, const char* expected, const char* file, size_t line)
516c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    {
517c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, T, V8UndefinedType> Property;
518c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Property* property = new Property(&document(), new GarbageCollectedScriptWrappable("holder"), Property::Ready);
519c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        size_t nResolveCalls = 0;
520c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ScriptValue actualValue;
521c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        String actual;
522c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
523c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ScriptState::Scope scope(mainScriptState());
5247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            property->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actualValue, nResolveCalls), notReached(currentScriptState()));
525c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
526c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        property->resolve(value);
527c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        isolate()->RunMicrotasks();
528c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
529c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ScriptState::Scope scope(mainScriptState());
530c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            actual = toCoreString(actualValue.v8Value()->ToString());
531c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
532c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (expected != actual) {
533c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ADD_FAILURE_AT(file, line) << "toV8Value returns an incorrect value.\n  Actual: " << actual.utf8().data() << "\nExpected: " << expected;
534c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return;
535c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
536c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
537c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
538c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
539c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithUndefined)
540c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
541c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    test(V8UndefinedType(), "undefined", __FILE__, __LINE__);
542c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
543c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
544c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithString)
545c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
546c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    test(String("hello"), "hello", __FILE__, __LINE__);
547c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
548c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
549c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithInteger)
550c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
551c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    test<int>(-1, "-1", __FILE__, __LINE__);
552c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
553c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
554197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} // namespace
555