File indexing completed on 2024-12-08 11:10:20
0001 /* This file is part of Kairo Timer 0002 0003 SPDX-FileCopyrightText: 2016 (c) Kevin Ottens <ervin@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 0007 */ 0008 0009 #include <QtTest> 0010 #include <QSignalSpy> 0011 0012 #include <memory> 0013 0014 #include "circuitcontrol.h" 0015 #include "timercontrol.h" 0016 0017 class CircuitControlTest : public QObject 0018 { 0019 Q_OBJECT 0020 private slots: 0021 void initTestCase() 0022 { 0023 qRegisterMetaType<TimerControl*>(); 0024 } 0025 0026 void shouldHaveDefaultState() 0027 { 0028 // GIVEN 0029 auto control = std::make_unique<CircuitControl>(); 0030 0031 // THEN 0032 QCOMPARE(control->model(), CircuitModel{}); 0033 QCOMPARE(control->timerControl(), static_cast<TimerControl*>(nullptr)); 0034 QCOMPARE(control->name(), QString()); 0035 QCOMPARE(control->size(), 0); 0036 QCOMPARE(control->remaining(), 0); 0037 QCOMPARE(control->currentTimer(), TimerModel{}); 0038 } 0039 0040 void shouldKnowTimerControl() 0041 { 0042 // GIVEN 0043 auto control = std::make_unique<CircuitControl>(); 0044 auto timerControlSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::timerControlChanged); 0045 auto timerControl = new TimerControl(control.get()); 0046 0047 // WHEN 0048 control->setTimerControl(timerControl); 0049 0050 // THEN 0051 QCOMPARE(control->timerControl(), timerControl); 0052 QCOMPARE(timerControlSpy->size(), 1); 0053 QCOMPARE(timerControlSpy->takeFirst().first().value<TimerControl*>(), timerControl); 0054 0055 // WHEN 0056 control->setTimerControl(timerControl); 0057 0058 // THEN 0059 QCOMPARE(control->timerControl(), timerControl); 0060 QCOMPARE(timerControlSpy->size(), 0); 0061 } 0062 0063 void shouldDeriveValuesFromModel_data() 0064 { 0065 QTest::addColumn<CircuitModel>("model"); 0066 0067 QTest::newRow("empty and unnamed") << CircuitModel{}; 0068 QTest::newRow("empty and named") << CircuitModel{"foo", {}}; 0069 QTest::newRow("with data") << CircuitModel{"foo", {{"rest", 10000}, {"run"}, {"rest", 5000}}}; 0070 } 0071 0072 void shouldDeriveValuesFromModel() 0073 { 0074 // GIVEN 0075 auto control = std::make_unique<CircuitControl>(); 0076 auto modelSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::modelChanged); 0077 auto nameSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::nameChanged); 0078 auto sizeSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::sizeChanged); 0079 auto remainingSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::remainingChanged); 0080 auto currentTimerSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::currentTimerChanged); 0081 0082 QFETCH(CircuitModel, model); 0083 0084 // WHEN 0085 control->setModel(model); 0086 0087 // THEN 0088 QCOMPARE(control->model(), model); 0089 QCOMPARE(control->name(), model.name()); 0090 QCOMPARE(control->size(), model.size()); 0091 QCOMPARE(control->remaining(), model.size()); 0092 0093 if (!model.name().isEmpty() || !model.isEmpty()) { 0094 QCOMPARE(modelSpy->size(), 1); 0095 QCOMPARE(modelSpy->takeFirst().first().value<CircuitModel>(), model); 0096 } else { 0097 QCOMPARE(modelSpy->size(), 0); 0098 } 0099 0100 if (!model.name().isEmpty()) { 0101 QCOMPARE(nameSpy->size(), 1); 0102 QCOMPARE(nameSpy->takeFirst().first().toString(), model.name()); 0103 } else { 0104 QCOMPARE(nameSpy->size(), 0); 0105 } 0106 0107 if (!model.isEmpty()) { 0108 QCOMPARE(sizeSpy->size(), 1); 0109 QCOMPARE(sizeSpy->takeFirst().first().toInt(), model.size()); 0110 0111 QCOMPARE(remainingSpy->size(), 1); 0112 QCOMPARE(remainingSpy->takeFirst().first().toInt(), model.size()); 0113 0114 if (!model.name().isEmpty()) { 0115 QCOMPARE(currentTimerSpy->size(), 1); 0116 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), model.at(0)); 0117 } else { 0118 QCOMPARE(currentTimerSpy->size(), 0); 0119 } 0120 } else { 0121 QCOMPARE(sizeSpy->size(), 0); 0122 QCOMPARE(remainingSpy->size(), 0); 0123 0124 if (!model.name().isEmpty()) { 0125 QCOMPARE(currentTimerSpy->size(), 1); 0126 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), TimerModel{}); 0127 } else { 0128 QCOMPARE(currentTimerSpy->size(), 0); 0129 } 0130 } 0131 0132 // WHEN 0133 control->setModel(model); 0134 0135 // THEN 0136 QCOMPARE(modelSpy->size(), 0); 0137 QCOMPARE(nameSpy->size(), 0); 0138 QCOMPARE(sizeSpy->size(), 0); 0139 QCOMPARE(remainingSpy->size(), 0); 0140 QCOMPARE(currentTimerSpy->size(), 0); 0141 } 0142 0143 void shouldDeriveValuesFromMovedModel_data() 0144 { 0145 shouldDeriveValuesFromModel_data(); 0146 } 0147 0148 void shouldDeriveValuesFromMovedModel() 0149 { 0150 // GIVEN 0151 auto control = std::make_unique<CircuitControl>(); 0152 auto modelSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::modelChanged); 0153 auto nameSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::nameChanged); 0154 auto sizeSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::sizeChanged); 0155 auto remainingSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::remainingChanged); 0156 auto currentTimerSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::currentTimerChanged); 0157 0158 QFETCH(CircuitModel, model); 0159 0160 // WHEN 0161 auto copy = model; 0162 control->setModel(std::move(copy)); // This should move it in place 0163 0164 // THEN 0165 QCOMPARE(control->model(), model); 0166 QCOMPARE(control->name(), model.name()); 0167 QCOMPARE(control->size(), model.size()); 0168 QCOMPARE(control->remaining(), model.size()); 0169 0170 if (!model.name().isEmpty() || !model.isEmpty()) { 0171 QCOMPARE(modelSpy->size(), 1); 0172 QCOMPARE(modelSpy->takeFirst().first().value<CircuitModel>(), model); 0173 } else { 0174 QCOMPARE(modelSpy->size(), 0); 0175 } 0176 0177 if (!model.name().isEmpty()) { 0178 QCOMPARE(nameSpy->size(), 1); 0179 QCOMPARE(nameSpy->takeFirst().first().toString(), model.name()); 0180 } else { 0181 QCOMPARE(nameSpy->size(), 0); 0182 } 0183 0184 if (!model.isEmpty()) { 0185 QCOMPARE(sizeSpy->size(), 1); 0186 QCOMPARE(sizeSpy->takeFirst().first().toInt(), model.size()); 0187 0188 QCOMPARE(remainingSpy->size(), 1); 0189 QCOMPARE(remainingSpy->takeFirst().first().toInt(), model.size()); 0190 0191 if (!model.name().isEmpty()) { 0192 QCOMPARE(currentTimerSpy->size(), 1); 0193 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), model.at(0)); 0194 } else { 0195 QCOMPARE(currentTimerSpy->size(), 0); 0196 } 0197 } else { 0198 QCOMPARE(sizeSpy->size(), 0); 0199 QCOMPARE(remainingSpy->size(), 0); 0200 0201 if (!model.name().isEmpty()) { 0202 QCOMPARE(currentTimerSpy->size(), 1); 0203 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), TimerModel{}); 0204 } else { 0205 QCOMPARE(currentTimerSpy->size(), 0); 0206 } 0207 } 0208 0209 0210 // WHEN 0211 control->setModel(std::move(model)); 0212 0213 // THEN 0214 QCOMPARE(modelSpy->size(), 0); 0215 QCOMPARE(nameSpy->size(), 0); 0216 QCOMPARE(sizeSpy->size(), 0); 0217 QCOMPARE(remainingSpy->size(), 0); 0218 QCOMPARE(currentTimerSpy->size(), 0); 0219 } 0220 0221 void shouldPushNextTimerOnFinishOrSkip() 0222 { 0223 // GIVEN 0224 auto control = std::make_unique<CircuitControl>(); 0225 auto timerControl = new TimerControl(control.get()); 0226 0227 control->setModel({ 0228 "foo", 0229 { 0230 {"mooh"}, 0231 {"rest", 10000}, 0232 {"run"}, 0233 {"rest", 5000} 0234 } 0235 }); 0236 auto remainingSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::remainingChanged); 0237 auto currentTimerSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::currentTimerChanged); 0238 auto finishedSpy = std::make_unique<QSignalSpy>(control.get(), &CircuitControl::circuitFinished); 0239 0240 // WHEN 0241 control->nextTimer(); 0242 0243 // THEN 0244 QCOMPARE(control->currentTimer(), control->model().at(1)); 0245 QCOMPARE(control->remaining(), 3); 0246 QCOMPARE(remainingSpy->size(), 1); 0247 QCOMPARE(remainingSpy->takeFirst().first().toInt(), 3); 0248 QCOMPARE(currentTimerSpy->size(), 1); 0249 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), control->model().at(1)); 0250 QCOMPARE(finishedSpy->size(), 0); 0251 0252 // WHEN 0253 control->setTimerControl(timerControl); 0254 0255 // THEN 0256 QCOMPARE(timerControl->model(), control->currentTimer()); 0257 QCOMPARE(timerControl->model(), control->model().at(1)); 0258 QCOMPARE(control->remaining(), 3); 0259 QCOMPARE(remainingSpy->size(), 0); 0260 QCOMPARE(currentTimerSpy->size(), 0); 0261 QCOMPARE(finishedSpy->size(), 0); 0262 0263 // WHEN 0264 emit timerControl->timerFinished(); 0265 0266 // THEN 0267 QCOMPARE(timerControl->model(), control->currentTimer()); 0268 QCOMPARE(timerControl->model(), control->model().at(2)); 0269 QCOMPARE(control->remaining(), 2); 0270 QCOMPARE(remainingSpy->size(), 1); 0271 QCOMPARE(remainingSpy->takeFirst().first().toInt(), 2); 0272 QCOMPARE(currentTimerSpy->size(), 1); 0273 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), control->model().at(2)); 0274 QCOMPARE(finishedSpy->size(), 0); 0275 0276 // WHEN 0277 control->nextTimer(); 0278 0279 // THEN 0280 QCOMPARE(timerControl->model(), control->currentTimer()); 0281 QCOMPARE(timerControl->model(), control->model().at(3)); 0282 QCOMPARE(control->remaining(), 1); 0283 QCOMPARE(remainingSpy->size(), 1); 0284 QCOMPARE(remainingSpy->takeFirst().first().toInt(), 1); 0285 QCOMPARE(currentTimerSpy->size(), 1); 0286 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), control->model().at(3)); 0287 QCOMPARE(finishedSpy->size(), 0); 0288 0289 // WHEN 0290 control->nextTimer(); 0291 0292 // THEN 0293 QCOMPARE(timerControl->model(), control->currentTimer()); 0294 QCOMPARE(timerControl->model(), TimerModel{}); 0295 QCOMPARE(control->remaining(), 0); 0296 QCOMPARE(remainingSpy->size(), 1); 0297 QCOMPARE(remainingSpy->takeFirst().first().toInt(), 0); 0298 QCOMPARE(currentTimerSpy->size(), 1); 0299 QCOMPARE(currentTimerSpy->takeFirst().first().value<TimerModel>(), TimerModel{}); 0300 QCOMPARE(finishedSpy->size(), 1); 0301 } 0302 }; 0303 0304 QTEST_MAIN(CircuitControlTest) 0305 0306 #include "circuitcontroltest.moc"