Index: third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp |
diff --git a/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp b/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1830b53f5dd203ce78ecb1454d9ddf26f6216fe8 |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/dom/ScriptedAnimationControllerTest.cpp |
@@ -0,0 +1,184 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "core/dom/ScriptedAnimationController.h" |
+ |
+#include "core/dom/Document.h" |
+#include "core/dom/FrameRequestCallback.h" |
+#include "core/events/Event.h" |
+#include "core/events/EventListener.h" |
+#include "core/events/EventTarget.h" |
+#include "core/testing/DummyPageHolder.h" |
+#include "platform/heap/Handle.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "wtf/Functional.h" |
+#include <memory> |
+ |
+namespace blink { |
+ |
+class ScriptedAnimationControllerTest : public ::testing::Test { |
+ protected: |
+ void SetUp() override; |
+ |
+ Document& document() const { return m_dummyPageHolder->document(); } |
+ ScriptedAnimationController& controller() { return *m_controller; } |
+ |
+ private: |
+ std::unique_ptr<DummyPageHolder> m_dummyPageHolder; |
+ Persistent<ScriptedAnimationController> m_controller; |
+}; |
+ |
+void ScriptedAnimationControllerTest::SetUp() { |
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); |
+ |
+ // Note: The document doesn't know about this ScriptedAnimationController |
+ // instance, and will create another if |
+ // Document::ensureScriptedAnimationController is called. |
+ m_controller = |
+ wrapPersistent(ScriptedAnimationController::create(&document())); |
+} |
+ |
+namespace { |
+ |
+class TaskOrderObserver { |
+ public: |
+ std::unique_ptr<WTF::Closure> createTask(int id) { |
+ return WTF::bind(&TaskOrderObserver::runTask, unretained(this), id); |
+ } |
+ const Vector<int>& order() const { return m_order; } |
+ |
+ private: |
+ void runTask(int id) { m_order.append(id); } |
+ Vector<int> m_order; |
+}; |
+ |
+} // anonymous namespace |
+ |
+TEST_F(ScriptedAnimationControllerTest, EnqueueOneTask) { |
+ TaskOrderObserver observer; |
+ |
+ controller().enqueueTask(observer.createTask(1)); |
+ EXPECT_EQ(0u, observer.order().size()); |
+ |
+ controller().serviceScriptedAnimations(0); |
+ EXPECT_EQ(1u, observer.order().size()); |
+ EXPECT_EQ(1, observer.order()[0]); |
+} |
+ |
+TEST_F(ScriptedAnimationControllerTest, EnqueueTwoTasks) { |
+ TaskOrderObserver observer; |
+ |
+ controller().enqueueTask(observer.createTask(1)); |
+ controller().enqueueTask(observer.createTask(2)); |
+ EXPECT_EQ(0u, observer.order().size()); |
+ |
+ controller().serviceScriptedAnimations(0); |
+ EXPECT_EQ(2u, observer.order().size()); |
+ EXPECT_EQ(1, observer.order()[0]); |
+ EXPECT_EQ(2, observer.order()[1]); |
+} |
+ |
+namespace { |
+ |
+void enqueueTask(ScriptedAnimationController* controller, |
+ TaskOrderObserver* observer, |
+ int id) { |
+ controller->enqueueTask(observer->createTask(id)); |
+} |
+ |
+} // anonymous namespace |
+ |
+// A task enqueued while running tasks should not be run immediately after, but |
+// the next time tasks are run. |
+TEST_F(ScriptedAnimationControllerTest, EnqueueWithinTask) { |
+ TaskOrderObserver observer; |
+ |
+ controller().enqueueTask(observer.createTask(1)); |
+ controller().enqueueTask(WTF::bind( |
+ &enqueueTask, wrapPersistent(&controller()), unretained(&observer), 2)); |
+ controller().enqueueTask(observer.createTask(3)); |
+ EXPECT_EQ(0u, observer.order().size()); |
+ |
+ controller().serviceScriptedAnimations(0); |
+ EXPECT_EQ(2u, observer.order().size()); |
+ EXPECT_EQ(1, observer.order()[0]); |
+ EXPECT_EQ(3, observer.order()[1]); |
+ |
+ controller().serviceScriptedAnimations(0); |
+ EXPECT_EQ(3u, observer.order().size()); |
+ EXPECT_EQ(1, observer.order()[0]); |
+ EXPECT_EQ(3, observer.order()[1]); |
+ EXPECT_EQ(2, observer.order()[2]); |
+} |
+ |
+namespace { |
+ |
+class RunTaskEventListener final : public EventListener { |
+ public: |
+ RunTaskEventListener(std::unique_ptr<WTF::Closure> task) |
+ : EventListener(CPPEventListenerType), m_task(std::move(task)) {} |
+ void handleEvent(ExecutionContext*, Event*) override { (*m_task)(); } |
+ bool operator==(const EventListener& other) const override { |
+ return this == &other; |
+ } |
+ |
+ private: |
+ std::unique_ptr<WTF::Closure> m_task; |
+}; |
+ |
+} // anonymous namespace |
+ |
+// Tasks should be run after events are dispatched, even if they were enqueued |
+// first. |
+TEST_F(ScriptedAnimationControllerTest, EnqueueTaskAndEvent) { |
+ TaskOrderObserver observer; |
+ |
+ controller().enqueueTask(observer.createTask(1)); |
+ document().addEventListener("test", |
+ new RunTaskEventListener(observer.createTask(2))); |
+ Event* event = Event::create("test"); |
+ event->setTarget(&document()); |
+ controller().enqueueEvent(event); |
+ EXPECT_EQ(0u, observer.order().size()); |
+ |
+ controller().serviceScriptedAnimations(0); |
+ EXPECT_EQ(2u, observer.order().size()); |
+ EXPECT_EQ(2, observer.order()[0]); |
+ EXPECT_EQ(1, observer.order()[1]); |
+} |
+ |
+namespace { |
+ |
+class RunTaskCallback final : public FrameRequestCallback { |
+ public: |
+ RunTaskCallback(std::unique_ptr<WTF::Closure> task) |
+ : m_task(std::move(task)) {} |
+ void handleEvent(double) override { (*m_task)(); } |
+ |
+ private: |
+ std::unique_ptr<WTF::Closure> m_task; |
+}; |
+ |
+} // anonymous namespace |
+ |
+// Animation frame callbacks should be run after tasks, even if they were |
+// enqueued first. |
+TEST_F(ScriptedAnimationControllerTest, RegisterCallbackAndEnqueueTask) { |
+ TaskOrderObserver observer; |
+ |
+ Event* event = Event::create("test"); |
+ event->setTarget(&document()); |
+ |
+ controller().registerCallback(new RunTaskCallback(observer.createTask(1))); |
+ controller().enqueueTask(observer.createTask(2)); |
+ EXPECT_EQ(0u, observer.order().size()); |
+ |
+ controller().serviceScriptedAnimations(0); |
+ EXPECT_EQ(2u, observer.order().size()); |
+ EXPECT_EQ(2, observer.order()[0]); |
+ EXPECT_EQ(1, observer.order()[1]); |
+} |
+ |
+} // namespace blink |