File indexing completed on 2024-11-10 04:55:54

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "effect/timeline.h"
0011 
0012 #include <QTest>
0013 
0014 using namespace std::chrono_literals;
0015 
0016 // FIXME: Delete it in the future.
0017 Q_DECLARE_METATYPE(std::chrono::milliseconds)
0018 
0019 class TimeLineTest : public QObject
0020 {
0021     Q_OBJECT
0022 
0023 private Q_SLOTS:
0024     void testUpdateForward();
0025     void testUpdateBackward();
0026     void testUpdateFinished();
0027     void testToggleDirection();
0028     void testReset();
0029     void testSetElapsed_data();
0030     void testSetElapsed();
0031     void testSetDuration();
0032     void testSetDurationRetargeting();
0033     void testSetDurationRetargetingSmallDuration();
0034     void testRunning();
0035     void testStrictRedirectSourceMode_data();
0036     void testStrictRedirectSourceMode();
0037     void testRelaxedRedirectSourceMode_data();
0038     void testRelaxedRedirectSourceMode();
0039     void testStrictRedirectTargetMode_data();
0040     void testStrictRedirectTargetMode();
0041     void testRelaxedRedirectTargetMode_data();
0042     void testRelaxedRedirectTargetMode();
0043 };
0044 
0045 void TimeLineTest::testUpdateForward()
0046 {
0047     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0048     timeLine.setEasingCurve(QEasingCurve::Linear);
0049 
0050     // 0/1000
0051     timeLine.advance(0ms);
0052     QCOMPARE(timeLine.value(), 0.0);
0053     QVERIFY(!timeLine.done());
0054 
0055     // 100/1000
0056     timeLine.advance(100ms);
0057     QCOMPARE(timeLine.value(), 0.1);
0058     QVERIFY(!timeLine.done());
0059 
0060     // 400/1000
0061     timeLine.advance(400ms);
0062     QCOMPARE(timeLine.value(), 0.4);
0063     QVERIFY(!timeLine.done());
0064 
0065     // 900/1000
0066     timeLine.advance(900ms);
0067     QCOMPARE(timeLine.value(), 0.9);
0068     QVERIFY(!timeLine.done());
0069 
0070     // 1000/1000
0071     timeLine.advance(3000ms);
0072     QCOMPARE(timeLine.value(), 1.0);
0073     QVERIFY(timeLine.done());
0074 }
0075 
0076 void TimeLineTest::testUpdateBackward()
0077 {
0078     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Backward);
0079     timeLine.setEasingCurve(QEasingCurve::Linear);
0080 
0081     // 0/1000
0082     timeLine.advance(0ms);
0083     QCOMPARE(timeLine.value(), 1.0);
0084     QVERIFY(!timeLine.done());
0085 
0086     // 100/1000
0087     timeLine.advance(100ms);
0088     QCOMPARE(timeLine.value(), 0.9);
0089     QVERIFY(!timeLine.done());
0090 
0091     // 400/1000
0092     timeLine.advance(400ms);
0093     QCOMPARE(timeLine.value(), 0.6);
0094     QVERIFY(!timeLine.done());
0095 
0096     // 900/1000
0097     timeLine.advance(900ms);
0098     QCOMPARE(timeLine.value(), 0.1);
0099     QVERIFY(!timeLine.done());
0100 
0101     // 1000/1000
0102     timeLine.advance(3000ms);
0103     QCOMPARE(timeLine.value(), 0.0);
0104     QVERIFY(timeLine.done());
0105 }
0106 
0107 void TimeLineTest::testUpdateFinished()
0108 {
0109     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0110     timeLine.advance(0ms);
0111     timeLine.setEasingCurve(QEasingCurve::Linear);
0112 
0113     timeLine.advance(1000ms);
0114     QCOMPARE(timeLine.value(), 1.0);
0115     QVERIFY(timeLine.done());
0116 
0117     timeLine.advance(1042ms);
0118     QCOMPARE(timeLine.value(), 1.0);
0119     QVERIFY(timeLine.done());
0120 }
0121 
0122 void TimeLineTest::testToggleDirection()
0123 {
0124     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0125     timeLine.setEasingCurve(QEasingCurve::Linear);
0126 
0127     timeLine.advance(0ms);
0128     QCOMPARE(timeLine.value(), 0.0);
0129     QVERIFY(!timeLine.done());
0130 
0131     timeLine.advance(600ms);
0132     QCOMPARE(timeLine.value(), 0.6);
0133     QVERIFY(!timeLine.done());
0134 
0135     timeLine.toggleDirection();
0136     QCOMPARE(timeLine.value(), 0.6);
0137     QVERIFY(!timeLine.done());
0138 
0139     timeLine.advance(800ms);
0140     QCOMPARE(timeLine.value(), 0.4);
0141     QVERIFY(!timeLine.done());
0142 
0143     timeLine.advance(3000ms);
0144     QCOMPARE(timeLine.value(), 0.0);
0145     QVERIFY(timeLine.done());
0146 }
0147 
0148 void TimeLineTest::testReset()
0149 {
0150     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0151     timeLine.setEasingCurve(QEasingCurve::Linear);
0152     timeLine.advance(0ms);
0153 
0154     timeLine.advance(1000ms);
0155     QCOMPARE(timeLine.value(), 1.0);
0156     QVERIFY(timeLine.done());
0157 
0158     timeLine.reset();
0159     QCOMPARE(timeLine.value(), 0.0);
0160     QVERIFY(!timeLine.done());
0161 }
0162 
0163 void TimeLineTest::testSetElapsed_data()
0164 {
0165     QTest::addColumn<std::chrono::milliseconds>("duration");
0166     QTest::addColumn<std::chrono::milliseconds>("elapsed");
0167     QTest::addColumn<std::chrono::milliseconds>("expectedElapsed");
0168     QTest::addColumn<bool>("expectedDone");
0169     QTest::addColumn<bool>("initiallyDone");
0170 
0171     QTest::newRow("Less than duration, not finished") << 1000ms << 300ms << 300ms << false << false;
0172     QTest::newRow("Less than duration, finished") << 1000ms << 300ms << 300ms << false << true;
0173     QTest::newRow("Greater than duration, not finished") << 1000ms << 3000ms << 1000ms << true << false;
0174     QTest::newRow("Greater than duration, finished") << 1000ms << 3000ms << 1000ms << true << true;
0175     QTest::newRow("Equal to duration, not finished") << 1000ms << 1000ms << 1000ms << true << false;
0176     QTest::newRow("Equal to duration, finished") << 1000ms << 1000ms << 1000ms << true << true;
0177 }
0178 
0179 void TimeLineTest::testSetElapsed()
0180 {
0181     QFETCH(std::chrono::milliseconds, duration);
0182     QFETCH(std::chrono::milliseconds, elapsed);
0183     QFETCH(std::chrono::milliseconds, expectedElapsed);
0184     QFETCH(bool, expectedDone);
0185     QFETCH(bool, initiallyDone);
0186 
0187     KWin::TimeLine timeLine(duration, KWin::TimeLine::Forward);
0188     timeLine.setEasingCurve(QEasingCurve::Linear);
0189     timeLine.advance(0ms);
0190 
0191     if (initiallyDone) {
0192         timeLine.advance(duration);
0193         QVERIFY(timeLine.done());
0194     }
0195 
0196     timeLine.setElapsed(elapsed);
0197     QCOMPARE(timeLine.elapsed(), expectedElapsed);
0198     QCOMPARE(timeLine.done(), expectedDone);
0199 }
0200 
0201 void TimeLineTest::testSetDuration()
0202 {
0203     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0204     timeLine.setEasingCurve(QEasingCurve::Linear);
0205 
0206     QCOMPARE(timeLine.duration(), 1000ms);
0207 
0208     timeLine.setDuration(3000ms);
0209     QCOMPARE(timeLine.duration(), 3000ms);
0210 }
0211 
0212 void TimeLineTest::testSetDurationRetargeting()
0213 {
0214     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0215     timeLine.setEasingCurve(QEasingCurve::Linear);
0216     timeLine.advance(0ms);
0217 
0218     timeLine.advance(500ms);
0219     QCOMPARE(timeLine.value(), 0.5);
0220     QVERIFY(!timeLine.done());
0221 
0222     timeLine.setDuration(3000ms);
0223     QCOMPARE(timeLine.value(), 0.5);
0224     QVERIFY(!timeLine.done());
0225 }
0226 
0227 void TimeLineTest::testSetDurationRetargetingSmallDuration()
0228 {
0229     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0230     timeLine.setEasingCurve(QEasingCurve::Linear);
0231     timeLine.advance(0ms);
0232 
0233     timeLine.advance(999ms);
0234     QCOMPARE(timeLine.value(), 0.999);
0235     QVERIFY(!timeLine.done());
0236 
0237     timeLine.setDuration(3ms);
0238     QCOMPARE(timeLine.value(), 1.0);
0239     QVERIFY(timeLine.done());
0240 }
0241 
0242 void TimeLineTest::testRunning()
0243 {
0244     KWin::TimeLine timeLine(1000ms, KWin::TimeLine::Forward);
0245     timeLine.setEasingCurve(QEasingCurve::Linear);
0246     timeLine.advance(0ms);
0247 
0248     QVERIFY(!timeLine.running());
0249     QVERIFY(!timeLine.done());
0250 
0251     timeLine.advance(100ms);
0252     QVERIFY(timeLine.running());
0253     QVERIFY(!timeLine.done());
0254 
0255     timeLine.advance(1000ms);
0256     QVERIFY(!timeLine.running());
0257     QVERIFY(timeLine.done());
0258 }
0259 
0260 void TimeLineTest::testStrictRedirectSourceMode_data()
0261 {
0262     QTest::addColumn<KWin::TimeLine::Direction>("initialDirection");
0263     QTest::addColumn<qreal>("initialValue");
0264     QTest::addColumn<KWin::TimeLine::Direction>("finalDirection");
0265     QTest::addColumn<qreal>("finalValue");
0266 
0267     QTest::newRow("forward -> backward") << KWin::TimeLine::Forward << 0.0 << KWin::TimeLine::Backward << 0.0;
0268     QTest::newRow("backward -> forward") << KWin::TimeLine::Backward << 1.0 << KWin::TimeLine::Forward << 1.0;
0269 }
0270 
0271 void TimeLineTest::testStrictRedirectSourceMode()
0272 {
0273     QFETCH(KWin::TimeLine::Direction, initialDirection);
0274     KWin::TimeLine timeLine(1000ms, initialDirection);
0275     timeLine.setEasingCurve(QEasingCurve::Linear);
0276     timeLine.setSourceRedirectMode(KWin::TimeLine::RedirectMode::Strict);
0277 
0278     QTEST(timeLine.direction(), "initialDirection");
0279     QTEST(timeLine.value(), "initialValue");
0280     QCOMPARE(timeLine.sourceRedirectMode(), KWin::TimeLine::RedirectMode::Strict);
0281     QVERIFY(!timeLine.running());
0282     QVERIFY(!timeLine.done());
0283 
0284     QFETCH(KWin::TimeLine::Direction, finalDirection);
0285     timeLine.setDirection(finalDirection);
0286 
0287     QTEST(timeLine.direction(), "finalDirection");
0288     QTEST(timeLine.value(), "finalValue");
0289     QCOMPARE(timeLine.sourceRedirectMode(), KWin::TimeLine::RedirectMode::Strict);
0290     QVERIFY(!timeLine.running());
0291     QVERIFY(timeLine.done());
0292 }
0293 
0294 void TimeLineTest::testRelaxedRedirectSourceMode_data()
0295 {
0296     QTest::addColumn<KWin::TimeLine::Direction>("initialDirection");
0297     QTest::addColumn<qreal>("initialValue");
0298     QTest::addColumn<KWin::TimeLine::Direction>("finalDirection");
0299     QTest::addColumn<qreal>("finalValue");
0300 
0301     QTest::newRow("forward -> backward") << KWin::TimeLine::Forward << 0.0 << KWin::TimeLine::Backward << 1.0;
0302     QTest::newRow("backward -> forward") << KWin::TimeLine::Backward << 1.0 << KWin::TimeLine::Forward << 0.0;
0303 }
0304 
0305 void TimeLineTest::testRelaxedRedirectSourceMode()
0306 {
0307     QFETCH(KWin::TimeLine::Direction, initialDirection);
0308     KWin::TimeLine timeLine(1000ms, initialDirection);
0309     timeLine.setEasingCurve(QEasingCurve::Linear);
0310     timeLine.setSourceRedirectMode(KWin::TimeLine::RedirectMode::Relaxed);
0311 
0312     QTEST(timeLine.direction(), "initialDirection");
0313     QTEST(timeLine.value(), "initialValue");
0314     QCOMPARE(timeLine.sourceRedirectMode(), KWin::TimeLine::RedirectMode::Relaxed);
0315     QVERIFY(!timeLine.running());
0316     QVERIFY(!timeLine.done());
0317 
0318     QFETCH(KWin::TimeLine::Direction, finalDirection);
0319     timeLine.setDirection(finalDirection);
0320 
0321     QTEST(timeLine.direction(), "finalDirection");
0322     QTEST(timeLine.value(), "finalValue");
0323     QCOMPARE(timeLine.sourceRedirectMode(), KWin::TimeLine::RedirectMode::Relaxed);
0324     QVERIFY(!timeLine.running());
0325     QVERIFY(!timeLine.done());
0326 }
0327 
0328 void TimeLineTest::testStrictRedirectTargetMode_data()
0329 {
0330     QTest::addColumn<KWin::TimeLine::Direction>("initialDirection");
0331     QTest::addColumn<qreal>("initialValue");
0332     QTest::addColumn<KWin::TimeLine::Direction>("finalDirection");
0333     QTest::addColumn<qreal>("finalValue");
0334 
0335     QTest::newRow("forward -> backward") << KWin::TimeLine::Forward << 0.0 << KWin::TimeLine::Backward << 1.0;
0336     QTest::newRow("backward -> forward") << KWin::TimeLine::Backward << 1.0 << KWin::TimeLine::Forward << 0.0;
0337 }
0338 
0339 void TimeLineTest::testStrictRedirectTargetMode()
0340 {
0341     QFETCH(KWin::TimeLine::Direction, initialDirection);
0342     KWin::TimeLine timeLine(1000ms, initialDirection);
0343     timeLine.setEasingCurve(QEasingCurve::Linear);
0344     timeLine.setTargetRedirectMode(KWin::TimeLine::RedirectMode::Strict);
0345     timeLine.advance(0ms);
0346 
0347     QTEST(timeLine.direction(), "initialDirection");
0348     QTEST(timeLine.value(), "initialValue");
0349     QCOMPARE(timeLine.targetRedirectMode(), KWin::TimeLine::RedirectMode::Strict);
0350     QVERIFY(!timeLine.running());
0351     QVERIFY(!timeLine.done());
0352 
0353     timeLine.advance(1000ms);
0354     QTEST(timeLine.value(), "finalValue");
0355     QVERIFY(!timeLine.running());
0356     QVERIFY(timeLine.done());
0357 
0358     QFETCH(KWin::TimeLine::Direction, finalDirection);
0359     timeLine.setDirection(finalDirection);
0360 
0361     QTEST(timeLine.direction(), "finalDirection");
0362     QTEST(timeLine.value(), "finalValue");
0363     QVERIFY(!timeLine.running());
0364     QVERIFY(timeLine.done());
0365 }
0366 
0367 void TimeLineTest::testRelaxedRedirectTargetMode_data()
0368 {
0369     QTest::addColumn<KWin::TimeLine::Direction>("initialDirection");
0370     QTest::addColumn<qreal>("initialValue");
0371     QTest::addColumn<KWin::TimeLine::Direction>("finalDirection");
0372     QTest::addColumn<qreal>("finalValue");
0373 
0374     QTest::newRow("forward -> backward") << KWin::TimeLine::Forward << 0.0 << KWin::TimeLine::Backward << 1.0;
0375     QTest::newRow("backward -> forward") << KWin::TimeLine::Backward << 1.0 << KWin::TimeLine::Forward << 0.0;
0376 }
0377 
0378 void TimeLineTest::testRelaxedRedirectTargetMode()
0379 {
0380     QFETCH(KWin::TimeLine::Direction, initialDirection);
0381     KWin::TimeLine timeLine(1000ms, initialDirection);
0382     timeLine.setEasingCurve(QEasingCurve::Linear);
0383     timeLine.setTargetRedirectMode(KWin::TimeLine::RedirectMode::Relaxed);
0384     timeLine.advance(0ms);
0385 
0386     QTEST(timeLine.direction(), "initialDirection");
0387     QTEST(timeLine.value(), "initialValue");
0388     QCOMPARE(timeLine.targetRedirectMode(), KWin::TimeLine::RedirectMode::Relaxed);
0389     QVERIFY(!timeLine.running());
0390     QVERIFY(!timeLine.done());
0391 
0392     timeLine.advance(1000ms);
0393     QTEST(timeLine.value(), "finalValue");
0394     QVERIFY(!timeLine.running());
0395     QVERIFY(timeLine.done());
0396 
0397     QFETCH(KWin::TimeLine::Direction, finalDirection);
0398     timeLine.setDirection(finalDirection);
0399     timeLine.advance(1000ms);
0400 
0401     QTEST(timeLine.direction(), "finalDirection");
0402     QTEST(timeLine.value(), "finalValue");
0403     QVERIFY(!timeLine.running());
0404     QVERIFY(!timeLine.done());
0405 
0406     timeLine.advance(2000ms);
0407     QTEST(timeLine.direction(), "finalDirection");
0408     QTEST(timeLine.value(), "initialValue");
0409     QVERIFY(!timeLine.running());
0410     QVERIFY(timeLine.done());
0411 }
0412 
0413 QTEST_MAIN(TimeLineTest)
0414 
0415 #include "timelinetest.moc"