| // Copyright 2019 The PDFium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "core/fxcrt/cfx_timer.h" |
| |
| #include <memory> |
| |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using testing::_; |
| using testing::DoAll; |
| using testing::Return; |
| using testing::SaveArg; |
| |
| namespace { |
| |
| class MockTimerScheduler : public CFX_Timer::HandlerIface { |
| public: |
| MOCK_METHOD(int, SetTimer, (int32_t uElapse, TimerCallback lpTimerFunc)); |
| MOCK_METHOD(void, KillTimer, (int32_t nID)); |
| }; |
| |
| class MockTimerCallback : public CFX_Timer::CallbackIface { |
| public: |
| MOCK_METHOD(void, OnTimerFired, ()); |
| }; |
| |
| } // namespace |
| |
| class CFXTimer : public testing::Test { |
| void SetUp() override { CFX_Timer::InitializeGlobals(); } |
| void TearDown() override { CFX_Timer::DestroyGlobals(); } |
| }; |
| |
| TEST_F(CFXTimer, ValidTimers) { |
| CFX_Timer::HandlerIface::TimerCallback fn1 = nullptr; |
| CFX_Timer::HandlerIface::TimerCallback fn2 = nullptr; |
| |
| MockTimerScheduler scheduler; |
| EXPECT_CALL(scheduler, SetTimer(100, _)) |
| .WillOnce(DoAll(SaveArg<1>(&fn1), Return(1001))); |
| EXPECT_CALL(scheduler, SetTimer(200, _)) |
| .WillOnce(DoAll(SaveArg<1>(&fn2), Return(1002))); |
| EXPECT_CALL(scheduler, KillTimer(1001)); |
| EXPECT_CALL(scheduler, KillTimer(1002)); |
| |
| MockTimerCallback cb1; |
| EXPECT_CALL(cb1, OnTimerFired()).Times(1); |
| |
| MockTimerCallback cb2; |
| EXPECT_CALL(cb2, OnTimerFired()).Times(2); |
| |
| auto timer1 = std::make_unique<CFX_Timer>(&scheduler, &cb1, 100); |
| auto timer2 = std::make_unique<CFX_Timer>(&scheduler, &cb2, 200); |
| EXPECT_TRUE(timer1->HasValidID()); |
| EXPECT_TRUE(timer2->HasValidID()); |
| |
| // Fire some timers. |
| ASSERT_TRUE(fn1); |
| ASSERT_TRUE(fn2); |
| (*fn1)(1001); |
| (*fn1)(1002); |
| (*fn1)(1002); |
| } |
| |
| TEST_F(CFXTimer, MisbehavingEmbedder) { |
| CFX_Timer::HandlerIface::TimerCallback fn1 = nullptr; |
| |
| MockTimerScheduler scheduler; |
| EXPECT_CALL(scheduler, SetTimer(100, _)) |
| .WillOnce(DoAll(SaveArg<1>(&fn1), Return(1001))); |
| EXPECT_CALL(scheduler, KillTimer(1001)); |
| |
| MockTimerCallback cb1; |
| EXPECT_CALL(cb1, OnTimerFired()).Times(0); |
| |
| { |
| auto timer1 = std::make_unique<CFX_Timer>(&scheduler, &cb1, 100); |
| EXPECT_TRUE(timer1->HasValidID()); |
| |
| // Fire callback with bad arguments. |
| ASSERT_TRUE(fn1); |
| (*fn1)(-1); |
| (*fn1)(0); |
| (*fn1)(1002); |
| } |
| |
| // Fire callback against stale timer. |
| (*fn1)(1001); |
| } |