@@ -14,11 +14,61 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−#include "homekeywatcher.h"
17+#include "HomeKeyWatcher.h"
1818
1919#include <QTest>
2020#include <QSignalSpy>
2121
22+
23+namespace UnityUtil {
24+class FakeElapsedTimer : public AbstractElapsedTimer {
25+public:
26+ static qint64 msecsSinceEpoch;
27+
28+ FakeElapsedTimer() { start(); }
29+
30+ void start() override { m_msecsSinceReference = msecsSinceEpoch; }
31+ qint64 msecsSinceReference() const override { return m_msecsSinceReference; }
32+ qint64 elapsed() const override { return msecsSinceEpoch - m_msecsSinceReference; }
33+
34+private:
35+ qint64 m_msecsSinceReference;
36+};
37+qint64 FakeElapsedTimer::msecsSinceEpoch = 0;
38+
39+class FakeTimer : public AbstractTimer
40+{
41+ Q_OBJECT
42+public:
43+ FakeTimer(QObject *parent = nullptr);
44+
45+ void update();
46+ qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
47+
48+ int interval() const override;
49+ void setInterval(int msecs) override;
50+ void start() override;
51+ bool isSingleShot() const override;
52+ void setSingleShot(bool value) override;
53+private:
54+ int m_interval;
55+ bool m_singleShot;
56+ qint64 m_nextTimeoutTime;
57+};
58+
59+class FakeTimerFactory : public AbstractTimerFactory
60+{
61+public:
62+ FakeTimerFactory();
63+ virtual ~FakeTimerFactory();
64+
65+ void updateTime(qint64 targetTime);
66+
67+ AbstractTimer *create(QObject *parent = nullptr) override;
68+ QList<QPointer<FakeTimer>> timers;
69+};
70+} // namespace UnityUtil
71+
2272using namespace UnityUtil;
2373
2474class HomeKeyWatcherTest : public QObject {
@@ -166,6 +216,107 @@ void HomeKeyWatcherTest::tapWhileTouching()
166216 QCOMPARE(activatedSpy.count(), 0);
167217}
168218
219+/////////////////////////////////// FakeTimer //////////////////////////////////
220+
221+FakeTimer::FakeTimer(QObject *parent)
222+ : UnityUtil::AbstractTimer(parent)
223+ , m_interval(0)
224+ , m_singleShot(true)
225+{
226+}
227+
228+void FakeTimer::update()
229+{
230+ if (!isRunning()) {
231+ return;
232+ }
233+
234+ if (m_nextTimeoutTime <= FakeElapsedTimer::msecsSinceEpoch) {
235+ if (isSingleShot()) {
236+ stop();
237+ } else {
238+ m_nextTimeoutTime += interval();
239+ }
240+ Q_EMIT timeout();
241+ }
242+}
243+
244+void FakeTimer::start()
245+{
246+ AbstractTimer::start();
247+ m_nextTimeoutTime = FakeElapsedTimer::msecsSinceEpoch + (qint64)interval();
248+}
249+
250+int FakeTimer::interval() const
251+{
252+ return m_interval;
253+}
254+
255+void FakeTimer::setInterval(int msecs)
256+{
257+ m_interval = msecs;
258+}
259+
260+bool FakeTimer::isSingleShot() const
261+{
262+ return m_singleShot;
263+}
264+
265+void FakeTimer::setSingleShot(bool value)
266+{
267+ m_singleShot = value;
268+}
269+
270+/////////////////////////////////// FakeTimerFactory //////////////////////////////////
271+
272+FakeTimerFactory::FakeTimerFactory()
273+{
274+}
275+
276+FakeTimerFactory::~FakeTimerFactory()
277+{
278+ for (int i = 0; i < timers.count(); ++i) {
279+ FakeTimer *timer = timers[i].data();
280+ if (timer) {
281+ delete timer;
282+ }
283+ }
284+}
285+
286+void FakeTimerFactory::updateTime(qint64 targetTime)
287+{
288+ qint64 minTimeoutTime = targetTime;
289+
290+ for (int i = 0; i < timers.count(); ++i) {
291+ FakeTimer *timer = timers[i].data();
292+ if (timer && timer->isRunning() && timer->nextTimeoutTime() < minTimeoutTime) {
293+ minTimeoutTime = timer->nextTimeoutTime();
294+ }
295+ }
296+
297+ FakeElapsedTimer::msecsSinceEpoch = minTimeoutTime;
298+
299+ for (int i = 0; i < timers.count(); ++i) {
300+ FakeTimer *timer = timers[i].data();
301+ if (timer) {
302+ timer->update();
303+ }
304+ }
305+
306+ if (FakeElapsedTimer::msecsSinceEpoch < targetTime) {
307+ updateTime(targetTime);
308+ }
309+}
310+
311+AbstractTimer *FakeTimerFactory::create(QObject *parent)
312+{
313+ FakeTimer *fakeTimer = new FakeTimer(parent);
314+
315+ timers.append(fakeTimer);
316+
317+ return fakeTimer;
318+}
319+
169320QTEST_GUILESS_MAIN(HomeKeyWatcherTest)
170321
171322#include "homekeywatchertest.moc"