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"