Chromium Code Reviews| Index: Source/platform/Timer.h |
| diff --git a/Source/platform/Timer.h b/Source/platform/Timer.h |
| index 4bf89004d96fcfb407e6166329c946d56dac99f5..c8a77d1eae376e990a51997a25972025f5131473 100644 |
| --- a/Source/platform/Timer.h |
| +++ b/Source/platform/Timer.h |
| @@ -105,8 +105,12 @@ private: |
| friend class TimerHeapReference; |
| }; |
| +template <typename TimerFiredClass> class MockableTimer; |
| + |
| template <typename TimerFiredClass> |
| -class Timer FINAL : public TimerBase { |
| +class Timer : public TimerBase { |
| + friend class MockableTimer<TimerFiredClass>; |
| + |
| public: |
| typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*); |
| @@ -120,6 +124,47 @@ private: |
| TimerFiredFunction m_function; |
| }; |
| +// A mockable timer is useful in manually controlling timers from tests |
| +// to avoid flakiness. To access a specific instance in layout tests, |
| +// it has to be plumbed through internals. The plan is to eventually have |
| +// a mocked system clock that would make this unnecessary. |
|
eseidel
2014/01/21 21:24:42
If this is no longer the plan, we should update th
|
| +template <typename TimerFiredClass> |
| +class MockableTimer FINAL : public Timer<TimerFiredClass> { |
| +public: |
| + typedef typename Timer<TimerFiredClass>::TimerFiredFunction TimerFiredFunction; |
| + |
| + MockableTimer(TimerFiredClass* o, TimerFiredFunction f) |
| + : Timer<TimerFiredClass>(o, f) |
| + , m_manualMode(false) |
| + , m_firePending(false) |
| + { |
| + } |
| + |
| + void setManualModeForTesting(bool manualMode) { m_manualMode = manualMode; } |
| + |
| + void manualFireForTesting() |
| + { |
| + ASSERT(m_manualMode); |
| + ASSERT(Timer<TimerFiredClass>::isActive() || m_firePending); |
| + Timer<TimerFiredClass>::fired(); |
| + if (!Timer<TimerFiredClass>::repeatInterval()) |
| + Timer<TimerFiredClass>::stop(); |
| + m_firePending = false; |
| + } |
| + |
| +private: |
| + bool m_manualMode; |
| + bool m_firePending; |
| + |
| + virtual void fired() OVERRIDE |
| + { |
| + if (m_manualMode) |
| + m_firePending = true; |
| + else |
| + Timer<TimerFiredClass>::fired(); |
| + } |
| +}; |
| + |
| inline bool TimerBase::isActive() const |
| { |
| ASSERT(m_thread == currentThread()); |