File indexing completed on 2024-04-28 17:08:17
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 }