Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Unified Diff: third_party/WebKit/Source/core/frame/DOMTimerTest.cpp

Issue 2694743004: Reset the nesting level for setInterval after completion. (Closed)
Patch Set: remove redundant copy of ExecutionContext Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/frame/DOMTimer.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/frame/DOMTimerTest.cpp
diff --git a/third_party/WebKit/Source/core/frame/DOMTimerTest.cpp b/third_party/WebKit/Source/core/frame/DOMTimerTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..787befa6f8fd28728e0989d1ff2f74c89b47b847
--- /dev/null
+++ b/third_party/WebKit/Source/core/frame/DOMTimerTest.cpp
@@ -0,0 +1,133 @@
+// Copyright 2017 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/frame/DOMTimer.h"
+
+#include <vector>
+
+#include "bindings/core/v8/ScriptController.h"
+#include "core/dom/Document.h"
+#include "core/layout/LayoutTestHelper.h"
+#include "platform/testing/TestingPlatformSupport.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::DoubleNear;
+using testing::ElementsAreArray;
+using testing::Matcher;
+
+namespace blink {
+
+namespace {
+
+class DOMTimerTest : public RenderingTest {
+ public:
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+ m_platform;
+
+ // Expected time between each iterator for setInterval(..., 1) or nested
+ // setTimeout(..., 1) are 1, 1, 1, 1, 4, 4, ... as a minumum clamp of 4m
+ // is applied from the 5th iteration onwards.
+ const std::vector<Matcher<double>> kExpectedTimings = {
+ DoubleNear(1., 0.000001), DoubleNear(1., 0.000001),
+ DoubleNear(1., 0.000001), DoubleNear(1., 0.000001),
+ DoubleNear(4., 0.000001), DoubleNear(4., 0.000001),
+ };
+
+ void SetUp() override {
+ m_platform->setAutoAdvanceNowToPendingTasks(true);
+ // Advance timer manually as RenderingTest expects the time to be non-zero.
+ m_platform->advanceClockSeconds(1.);
+ RenderingTest::SetUp();
+ // Advance timer again as otherwise the time between the first call to
+ // setInterval and it running will be off by 5us.
+ m_platform->advanceClockSeconds(1);
+ document().settings()->setScriptEnabled(true);
+ }
+
+ v8::Local<v8::Value> EvalExpression(const char* expr) {
+ return document().frame()->script().executeScriptInMainWorldAndReturnValue(
+ ScriptSourceCode(expr));
+ }
+
+ Vector<double> toDoubleArray(v8::Local<v8::Value> value,
+ v8::HandleScope& scope) {
+ NonThrowableExceptionState exceptionState;
+ return toImplArray<Vector<double>>(value, 0, scope.GetIsolate(),
+ exceptionState);
+ }
+
+ void ExecuteScriptAndWaitUntilIdle(const char* scriptText) {
+ ScriptSourceCode script(scriptText);
+ document().frame()->script().executeScriptInMainWorld(script);
+ m_platform->runUntilIdle();
+ }
+};
+
+const char* kSetTimeoutScriptText =
+ "var id;"
+ "var last = performance.now();"
+ "var times = [];"
+ "function nestSetTimeouts() {"
+ " var current = performance.now();"
+ " var elapsed = current - last;"
+ " last = current;"
+ " times.push(elapsed);"
+ " if (times.length < 6) {"
+ " setTimeout(nestSetTimeouts, 1);"
+ " }"
+ "}"
+ "setTimeout(nestSetTimeouts, 1);";
+
+TEST_F(DOMTimerTest, setTimeout_ClampsAfter4Nestings) {
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+
+ ExecuteScriptAndWaitUntilIdle(kSetTimeoutScriptText);
+
+ auto times(toDoubleArray(EvalExpression("times"), scope));
+
+ EXPECT_THAT(times, ElementsAreArray(kExpectedTimings));
+}
+
+const char* kSetIntervalScriptText =
+ "var last = performance.now();"
+ "var times = [];"
+ "var id = setInterval(function() {"
+ " var current = performance.now();"
+ " var elapsed = current - last;"
+ " last = current;"
+ " times.push(elapsed);"
+ " if (times.length > 5) {"
+ " clearInterval(id);"
+ " }"
+ "}, 1);";
+
+TEST_F(DOMTimerTest, setInterval_ClampsAfter4Iterations) {
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+
+ ExecuteScriptAndWaitUntilIdle(kSetIntervalScriptText);
+
+ auto times(toDoubleArray(EvalExpression("times"), scope));
+
+ EXPECT_THAT(times, ElementsAreArray(kExpectedTimings));
+}
+
+TEST_F(DOMTimerTest, setInterval_NestingResetsForLaterCalls) {
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+
+ ExecuteScriptAndWaitUntilIdle(kSetIntervalScriptText);
+
+ // Run the setIntervalScript again to verify that the clamp imposed for
+ // nesting beyond 4 levels is reset when setInterval is called again in the
+ // original scope but after the original setInterval has completed.
+ ExecuteScriptAndWaitUntilIdle(kSetIntervalScriptText);
+
+ auto times(toDoubleArray(EvalExpression("times"), scope));
+
+ EXPECT_THAT(times, ElementsAreArray(kExpectedTimings));
+}
+
+} // namespace
+
+} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/frame/DOMTimer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698