File indexing completed on 2024-04-21 05:54:06

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-or-later
0003 */
0004 
0005 #include "rsitimer_test.h"
0006 
0007 #include "rsiglobals.h"
0008 #include "rsitimer.h"
0009 
0010 static constexpr int RELAX_ENDED_MAGIC_VALUE = -1;
0011 
0012 RSITimerTest::RSITimerTest(void)
0013 {
0014     m_intervals.resize(INTERVAL_COUNT);
0015     m_intervals[TINY_BREAK_INTERVAL] = 15 * 60;
0016     m_intervals[TINY_BREAK_DURATION] = 20;
0017     m_intervals[TINY_BREAK_THRESHOLD] = 60;
0018     m_intervals[BIG_BREAK_INTERVAL] = 60 * 60;
0019     m_intervals[BIG_BREAK_DURATION] = 60;
0020     m_intervals[BIG_BREAK_THRESHOLD] = 5 * 60;
0021     m_intervals[POSTPONE_BREAK_INTERVAL] = 3 * 60;
0022     m_intervals[PATIENCE_INTERVAL] = 30;
0023     m_intervals[SHORT_INPUT_INTERVAL] = 2;
0024 }
0025 
0026 void RSITimerTest::triggerSimpleTinyBreak()
0027 {
0028     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0029     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0030     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0031 
0032     QSignalSpy spyEndShortBreak(&timer, SIGNAL(endShortBreak()));
0033 
0034     // Part one, no idleness till small break.
0035     QSignalSpy spy1Relax(&timer, SIGNAL(relax(int, bool)));
0036     QSignalSpy spy1UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0037 
0038     idle_time_ptr->setIdleTime(0);
0039     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0040         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0041         timer.timeout();
0042     }
0043 
0044     QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0045 
0046     QCOMPARE(spy1Relax.count(), 1);
0047     QList<QVariant> spy1RelaxSignals = spy1Relax.takeFirst();
0048     QCOMPARE(spy1RelaxSignals.at(0).toInt(), m_intervals[TINY_BREAK_DURATION]);
0049     QCOMPARE(spy1RelaxSignals.at(1).toBool(), false);
0050 
0051     QCOMPARE(spy1UpdateIdleAvg.count(), m_intervals[TINY_BREAK_INTERVAL]);
0052     double lastAvg = 0;
0053     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0054         QList<QVariant> spy1UpdateIdleAvgSignals = spy1UpdateIdleAvg.takeFirst();
0055         bool ok;
0056         double newAvg = spy1UpdateIdleAvgSignals.at(0).toDouble(&ok);
0057         QVERIFY2(ok && (newAvg >= lastAvg) && (newAvg <= 100.0), QString("Unexpected newAvg value: %1, lastAvg: %2").arg(newAvg).arg(lastAvg).toLatin1());
0058     }
0059 
0060     // Part two, obeying and idle as suggested.
0061     QSignalSpy spy2Relax(&timer, SIGNAL(relax(int, bool)));
0062     QSignalSpy spy2UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0063     QSignalSpy spy2Minimize(&timer, SIGNAL(minimize()));
0064 
0065     for (int i = 0; i < m_intervals[TINY_BREAK_DURATION]; i++) {
0066         QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0067         idle_time_ptr->setIdleTime((i + 1) * 1000);
0068         timer.timeout();
0069     }
0070     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0071     QCOMPARE(spy2Minimize.count(), 1);
0072     QCOMPARE(spy2Relax.count(), m_intervals[TINY_BREAK_DURATION]);
0073     for (int i = 1; i < m_intervals[TINY_BREAK_DURATION]; i++) {
0074         QList<QVariant> spy2RelaxSignals = spy2Relax.takeFirst();
0075         QCOMPARE(spy2RelaxSignals.at(0).toInt(), m_intervals[TINY_BREAK_DURATION] - i);
0076     }
0077     QList<QVariant> spy2RelaxSignals = spy2Relax.takeFirst(); // The last one is special.
0078     QCOMPARE(spy2RelaxSignals.at(0).toInt(), RELAX_ENDED_MAGIC_VALUE);
0079     QCOMPARE(spyEndShortBreak.count(), 1);
0080 }
0081 
0082 void RSITimerTest::triggerComplexTinyBreak()
0083 {
0084     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0085     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0086     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0087 
0088     int part1 = 10; // Non-idle
0089     int part2 = 40; // Idle
0090     int part3 = m_intervals[TINY_BREAK_INTERVAL] - part1 - part2; // The rest non-idle.
0091 
0092     // Part 1, no idleness.
0093     QSignalSpy spy1Relax(&timer, SIGNAL(relax(int, bool)));
0094     QSignalSpy spy1UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0095     idle_time_ptr->setIdleTime(0);
0096     for (int i = 0; i < part1; i++) {
0097         timer.timeout();
0098         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0099     }
0100     QCOMPARE(spy1Relax.count(), 0);
0101     QCOMPARE(spy1UpdateIdleAvg.count(), part1);
0102 
0103     // Part 2, idle for a while.
0104     QSignalSpy spy2Relax(&timer, SIGNAL(relax(int, bool)));
0105     QSignalSpy spy2UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0106     for (int i = 0; i < part2; i++) {
0107         idle_time_ptr->setIdleTime((i + 1) * 1000);
0108         timer.timeout();
0109         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0110     }
0111     QCOMPARE(spy2Relax.count(), 0);
0112     QCOMPARE(spy2UpdateIdleAvg.count(), part2);
0113 
0114     // Part 3, non-idle till break.
0115     QSignalSpy spy3Relax(&timer, SIGNAL(relax(int, bool)));
0116     QSignalSpy spy3UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0117     for (int i = 0; i < part3; i++) {
0118         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0119         idle_time_ptr->setIdleTime(0);
0120         timer.timeout();
0121     }
0122     QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0123     QCOMPARE(spy3Relax.count(), 1);
0124 }
0125 
0126 void RSITimerTest::testSuspended()
0127 {
0128     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0129     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0130     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0131 
0132     timer.slotStop();
0133     QCOMPARE(timer.m_state, RSITimer::TimerState::Suspended);
0134 
0135     QSignalSpy spy1Relax(&timer, SIGNAL(relax(int, bool)));
0136     QSignalSpy spy1UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0137 
0138     // Not idle for long enough to have a break.
0139     idle_time_ptr->setIdleTime(0);
0140     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0141         timer.timeout();
0142         QCOMPARE(timer.m_state, RSITimer::TimerState::Suspended);
0143     }
0144     QCOMPARE(spy1Relax.count(), 0);
0145     QCOMPARE(spy1UpdateIdleAvg.count(), 0);
0146 
0147     timer.slotStart();
0148     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0149 }
0150 
0151 void RSITimerTest::triggerSimpleBigBreak()
0152 {
0153     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0154     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0155     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0156 
0157     int tinyBreaks = m_intervals[BIG_BREAK_INTERVAL] / (m_intervals[TINY_BREAK_INTERVAL] + m_intervals[PATIENCE_INTERVAL] + m_intervals[TINY_BREAK_DURATION]);
0158     // We don't tick big pause timer during tiny breaks and patience, so it will actually happen later.
0159     // In time the patience wears out, the tiny break could already accumulate some seconds due to SHORT_INPUT_INTERVAL filter, so substract them.
0160     int ticks = m_intervals[BIG_BREAK_INTERVAL]
0161         + tinyBreaks
0162             * (m_intervals[PATIENCE_INTERVAL] + m_intervals[TINY_BREAK_DURATION] - (m_intervals[PATIENCE_INTERVAL] - 1) % m_intervals[SHORT_INPUT_INTERVAL]);
0163 
0164     QSignalSpy spyEndLongBreak(&timer, SIGNAL(endLongBreak()));
0165 
0166     // Part one, no idleness till big break.
0167     QSignalSpy spy1Relax(&timer, SIGNAL(relax(int, bool)));
0168     QSignalSpy spy1UpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0169 
0170     idle_time_ptr->setIdleTime(0);
0171     for (int i = 0; i < ticks; i++) {
0172         timer.timeout();
0173     }
0174 
0175     // Number of relax updates during N tiny breaks, plus one for the actual big break.
0176     int relaxCountExp = tinyBreaks * (2 + m_intervals[PATIENCE_INTERVAL]) + 1;
0177     QCOMPARE(spy1Relax.count(), relaxCountExp);
0178     QVERIFY2(spy1UpdateIdleAvg.count() >= m_intervals[BIG_BREAK_INTERVAL], "Failed to update the indicator regularly.");
0179 
0180     // Part two, making the big break.
0181     QSignalSpy spy2Relax(&timer, SIGNAL(relax(int, bool)));
0182     for (int i = 0; i < m_intervals[BIG_BREAK_DURATION]; i++) {
0183         QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0184         idle_time_ptr->setIdleTime((i + 1) * 1000);
0185         timer.timeout();
0186     }
0187     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0188     QCOMPARE(spy2Relax.count(), m_intervals[BIG_BREAK_DURATION]);
0189     QCOMPARE(spyEndLongBreak.count(), 1);
0190 }
0191 
0192 void RSITimerTest::postponeBreak()
0193 {
0194     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0195     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0196     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0197 
0198     // Not idle for long enough to have a break.
0199     idle_time_ptr->setIdleTime(0);
0200     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0201         timer.timeout();
0202     }
0203     QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0204 
0205     QSignalSpy spyRelax(&timer, SIGNAL(relax(int, bool)));
0206     QSignalSpy spyMinimize(&timer, SIGNAL(minimize()));
0207     timer.postponeBreak();
0208 
0209     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0210 
0211     QList<QVariant> spyRelaxSignals = spyRelax.takeFirst();
0212     QCOMPARE(spyRelaxSignals.at(0).toInt(), RELAX_ENDED_MAGIC_VALUE);
0213     QCOMPARE(spyMinimize.count(), 1);
0214 
0215     // Waiting out postpone interval to confirm the break happens.
0216     for (int i = 0; i < m_intervals[POSTPONE_BREAK_INTERVAL]; i++) {
0217         timer.timeout();
0218     }
0219     QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0220 }
0221 
0222 void RSITimerTest::screenLock()
0223 {
0224     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0225     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0226     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0227 
0228     // Not idle for long enough to have a break.
0229     idle_time_ptr->setIdleTime(0);
0230     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0231         timer.timeout();
0232     }
0233     QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0234 
0235     QSignalSpy spyRelax(&timer, SIGNAL(relax(int, bool)));
0236     QSignalSpy spyMinimize(&timer, SIGNAL(minimize()));
0237     timer.slotLock();
0238 
0239     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0240 
0241     QList<QVariant> spyRelaxSignals = spyRelax.takeFirst();
0242     QCOMPARE(spyRelaxSignals.at(0).toInt(), RELAX_ENDED_MAGIC_VALUE);
0243     QCOMPARE(spyMinimize.count(), 1);
0244     QVERIFY2(timer.m_bigBreakCounter->counterLeft() < m_intervals[BIG_BREAK_INTERVAL], "Big break counter was reset on screen lock when it should have not.");
0245 }
0246 
0247 void RSITimerTest::skipBreak()
0248 {
0249     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0250     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0251     RSITimer timer(std::move(idle_time), m_intervals, true, true);
0252 
0253     // Not idle for long enough to have a break.
0254     idle_time_ptr->setIdleTime(0);
0255     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0256         timer.timeout();
0257     }
0258     QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0259 
0260     QSignalSpy spyRelax(&timer, SIGNAL(relax(int, bool)));
0261     QSignalSpy spyMinimize(&timer, SIGNAL(minimize()));
0262     timer.skipBreak();
0263 
0264     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0265 
0266     QList<QVariant> spyRelaxSignals = spyRelax.takeFirst();
0267     QCOMPARE(spyRelaxSignals.at(0).toInt(), RELAX_ENDED_MAGIC_VALUE);
0268     QCOMPARE(spyMinimize.count(), 1);
0269     QVERIFY2(timer.m_bigBreakCounter->counterLeft() < m_intervals[BIG_BREAK_INTERVAL], "Big break counter was reset on skip break when it should have not.");
0270 }
0271 
0272 void RSITimerTest::noPopupBreak()
0273 {
0274     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0275     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0276     RSITimer timer(std::move(idle_time), m_intervals, false, true);
0277 
0278     QSignalSpy spyStartShortBreak(&timer, SIGNAL(startShortBreak()));
0279     QSignalSpy spyEndShortBreak(&timer, SIGNAL(endShortBreak()));
0280 
0281     // Part one, no idleness till small break.
0282     QSignalSpy spy1BreakNow(&timer, SIGNAL(breakNow()));
0283     QSignalSpy spy1UpdateWidget(&timer, SIGNAL(updateWidget(int)));
0284 
0285     idle_time_ptr->setIdleTime(0);
0286     for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; i++) {
0287         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0288         timer.timeout();
0289     }
0290 
0291     // Popup is disabled so straight to breaking.
0292     QCOMPARE(spyStartShortBreak.count(), 1);
0293     QCOMPARE(timer.m_state, RSITimer::TimerState::Resting);
0294 
0295     QCOMPARE(spy1BreakNow.count(), 1);
0296     QList<QVariant> spy1UpdateWidgetSignals = spy1UpdateWidget.takeFirst();
0297     QCOMPARE(spy1UpdateWidgetSignals.at(0).toInt(), m_intervals[TINY_BREAK_DURATION]);
0298 
0299     // Part two, waiting out break.
0300     QSignalSpy spy2UpdateWidget(&timer, SIGNAL(updateWidget(int)));
0301     QSignalSpy spy2Minimize(&timer, SIGNAL(minimize()));
0302 
0303     for (int i = 0; i < m_intervals[TINY_BREAK_DURATION]; i++) {
0304         QCOMPARE(timer.m_state, RSITimer::TimerState::Resting);
0305         idle_time_ptr->setIdleTime((i + 1) * 1000);
0306         timer.timeout();
0307     }
0308     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0309     QCOMPARE(spy2Minimize.count(), 1);
0310     QCOMPARE(spy2UpdateWidget.count(), m_intervals[TINY_BREAK_DURATION] - 1);
0311     for (int i = 1; i < m_intervals[TINY_BREAK_DURATION]; i++) {
0312         QList<QVariant> spy2UpdateWidgetSignals = spy2UpdateWidget.takeFirst();
0313         QCOMPARE(spy2UpdateWidgetSignals.at(0).toInt(), m_intervals[TINY_BREAK_DURATION] - i);
0314     }
0315     QCOMPARE(spyEndShortBreak.count(), 1);
0316 }
0317 
0318 void RSITimerTest::regularBreaks()
0319 {
0320     std::unique_ptr<RSIIdleTimeFake> idle_time(new RSIIdleTimeFake());
0321     RSIIdleTimeFake *idle_time_ptr = idle_time.get();
0322     RSITimer timer(std::move(idle_time), m_intervals, true, false);
0323 
0324     QSignalSpy spyEndShortBreak(&timer, SIGNAL(endShortBreak()));
0325     QSignalSpy spyEndLongBreak(&timer, SIGNAL(endLongBreak()));
0326 
0327     int tinyBreaks = m_intervals[BIG_BREAK_INTERVAL] / (m_intervals[TINY_BREAK_INTERVAL] + m_intervals[PATIENCE_INTERVAL] + m_intervals[TINY_BREAK_DURATION]);
0328     int tick = 0;
0329 
0330     for (int j = 0; j < tinyBreaks; j++) {
0331         // Tiny break, mix of activity and idleness till small break.
0332         QSignalSpy spyRelax(&timer, SIGNAL(relax(int, bool)));
0333         QSignalSpy spyUpdateIdleAvg(&timer, SIGNAL(updateIdleAvg(double)));
0334 
0335         for (int i = 0; i < m_intervals[TINY_BREAK_INTERVAL]; ++i, ++tick) {
0336             QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0337             if (i % 2 == 0) {
0338                 idle_time_ptr->setIdleTime(0);
0339             } else {
0340                 idle_time_ptr->setIdleTime(1000);
0341             }
0342             timer.timeout();
0343         }
0344 
0345         for (int i = 0; i < m_intervals[TINY_BREAK_DURATION]; ++i, ++tick) {
0346             // No activity during break -- obeying.
0347             QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0348             idle_time_ptr->setIdleTime((i + 1) * 1000);
0349             timer.timeout();
0350         }
0351         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0352     }
0353 
0354     // Expected ticks till big break, accounting for pauses.
0355     int ticks = m_intervals[BIG_BREAK_INTERVAL] + tinyBreaks * m_intervals[TINY_BREAK_DURATION];
0356     for (int j = tick; j < ticks; j++) {
0357         QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0358         if (j % 2 == 0) {
0359             idle_time_ptr->setIdleTime(0);
0360         } else {
0361             idle_time_ptr->setIdleTime(1000);
0362         }
0363         timer.timeout();
0364     }
0365     for (int i = 0; i < m_intervals[BIG_BREAK_DURATION]; i++) {
0366         // No activity during break -- obeying.
0367         QCOMPARE(timer.m_state, RSITimer::TimerState::Suggesting);
0368         idle_time_ptr->setIdleTime((i + 1) * 1000);
0369         timer.timeout();
0370     }
0371     QCOMPARE(timer.m_state, RSITimer::TimerState::Monitoring);
0372 
0373     QCOMPARE(spyEndShortBreak.count(), tinyBreaks);
0374     QCOMPARE(spyEndLongBreak.count(), 1);
0375 }