1 /*
2     SPDX-FileCopyrightText: 2014 Dominik Haumann <dhaumann@kde.org>
3     SPDX-FileCopyrightText: 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "kmessagewidgetautotest.h"
9 
10 #include <QSignalSpy>
11 #include <QTest>
12 #include <kmessagewidget.h>
13 
14 QTEST_MAIN(KMessageWidgetTest)
15 
16 // KMessageWidget is currently hardcoded to a 500 ms timeline and default QTimeLine 40 ms update interval
17 // let's have 7 updates for now, should be save
18 const int overlappingWaitingTime = 280;
19 
20 // clang-format off
21 #define CHECK_FULLY_VISIBLE \
22     QVERIFY(w.isVisible()); \
23     QCOMPARE(w.height(), w.sizeHint().height()); \
24 
25 #define CHECK_FULLY_NOT_VISIBLE \
26     QCOMPARE(w.height(), 0); \
27     QVERIFY(!w.isVisible());
28 // clang-format on
29 
testAnimationSignals()30 void KMessageWidgetTest::testAnimationSignals()
31 {
32     KMessageWidget w(QStringLiteral("Hello world"));
33 
34     QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished);
35     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
36 
37     QCOMPARE(showSignalsSpy.count(), 0);
38 
39     //
40     // test: showing the message widget should emit showAnimationFinished()
41     // exactly once after the show animation is finished
42     //
43     w.animatedShow();
44 
45     QTRY_VERIFY(!w.isShowAnimationRunning());
46     QCOMPARE(showSignalsSpy.count(), 1);
47     CHECK_FULLY_VISIBLE
48 
49     //
50     // test: hiding the message widget should emit hideAnimationFinished()
51     // exactly once after the show animation is finished
52     //
53     w.animatedHide();
54 
55     QTRY_VERIFY(!w.isHideAnimationRunning());
56     QCOMPARE(hideSignalsSpy.count(), 1);
57     CHECK_FULLY_NOT_VISIBLE
58 }
59 
testShowOnVisible()60 void KMessageWidgetTest::testShowOnVisible()
61 {
62     KMessageWidget w(QStringLiteral("Hello world"));
63     QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished);
64     w.show();
65     CHECK_FULLY_VISIBLE
66 
67     // test: call show on visible
68     w.animatedShow();
69 
70     QTRY_VERIFY(!w.isShowAnimationRunning());
71     QCOMPARE(showSignalsSpy.count(), 1);
72     CHECK_FULLY_VISIBLE
73 }
74 
testHideOnInvisible()75 void KMessageWidgetTest::testHideOnInvisible()
76 {
77     KMessageWidget w(QStringLiteral("Hello world"));
78     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
79 
80     // test: call hide on invisible
81     w.animatedHide();
82 
83     QTRY_VERIFY(!w.isHideAnimationRunning());
84     QCOMPARE(hideSignalsSpy.count(), 1);
85     QVERIFY(!w.isVisible()); // Not CHECK_FULLY_NOT_VISIBLE because since it was never shown height is not what it would be otherwise
86 }
87 
testOverlappingShowAndHide_data()88 void KMessageWidgetTest::testOverlappingShowAndHide_data()
89 {
90     QTest::addColumn<bool>("delay");
91     QTest::newRow("instant") << false;
92     QTest::newRow("delay") << true;
93 }
94 
testOverlappingShowAndHide()95 void KMessageWidgetTest::testOverlappingShowAndHide()
96 {
97     QFETCH(bool, delay);
98 
99     KMessageWidget w(QStringLiteral("Hello world"));
100 
101     QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished);
102     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
103 
104     // test: call hide while show animation still running
105     w.animatedShow();
106     QVERIFY(w.isVisible()); // Not CHECK_FULLY_VISIBLE because we're not waiting for it to finish
107     if (delay) {
108         QTest::qWait(overlappingWaitingTime);
109     }
110     w.animatedHide();
111 
112     QVERIFY(!w.isShowAnimationRunning());
113     QCOMPARE(showSignalsSpy.count(), 1);
114 
115     QTRY_VERIFY(!w.isHideAnimationRunning());
116     QCOMPARE(hideSignalsSpy.count(), 1);
117     CHECK_FULLY_NOT_VISIBLE
118 }
119 
testOverlappingHideAndShow_data()120 void KMessageWidgetTest::testOverlappingHideAndShow_data()
121 {
122     QTest::addColumn<bool>("delay");
123     QTest::newRow("instant") << false;
124     QTest::newRow("delay") << true;
125 }
126 
testOverlappingHideAndShow()127 void KMessageWidgetTest::testOverlappingHideAndShow()
128 {
129     QFETCH(bool, delay);
130 
131     KMessageWidget w(QStringLiteral("Hello world"));
132     QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished);
133     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
134     w.show();
135     CHECK_FULLY_VISIBLE
136 
137     // test: call show while hide animation still running
138     w.animatedHide();
139     if (delay) {
140         QTest::qWait(overlappingWaitingTime);
141     }
142     w.animatedShow();
143 
144     QVERIFY(!w.isHideAnimationRunning());
145     QCOMPARE(hideSignalsSpy.count(), 1);
146 
147     QTRY_VERIFY(!w.isShowAnimationRunning());
148     QCOMPARE(showSignalsSpy.count(), 1);
149     CHECK_FULLY_VISIBLE
150 }
151 
testOverlappingDoubleShow_data()152 void KMessageWidgetTest::testOverlappingDoubleShow_data()
153 {
154     QTest::addColumn<bool>("delay");
155     QTest::newRow("instant") << false;
156     QTest::newRow("delay") << true;
157 }
158 
testOverlappingDoubleShow()159 void KMessageWidgetTest::testOverlappingDoubleShow()
160 {
161     QFETCH(bool, delay);
162 
163     KMessageWidget w(QStringLiteral("Hello world"));
164     QSignalSpy showSignalsSpy(&w, &KMessageWidget::showAnimationFinished);
165 
166     // test: call show while show animation still running
167     w.animatedShow();
168     if (delay) {
169         QTest::qWait(overlappingWaitingTime);
170     }
171     w.animatedShow();
172 
173     QTRY_VERIFY(!w.isShowAnimationRunning());
174     QCOMPARE(showSignalsSpy.count(), 1);
175     CHECK_FULLY_VISIBLE
176 }
177 
testOverlappingDoubleHide_data()178 void KMessageWidgetTest::testOverlappingDoubleHide_data()
179 {
180     QTest::addColumn<bool>("delay");
181     QTest::newRow("instant") << false;
182     QTest::newRow("delay") << true;
183 }
184 
testOverlappingDoubleHide()185 void KMessageWidgetTest::testOverlappingDoubleHide()
186 {
187     QFETCH(bool, delay);
188 
189     KMessageWidget w(QStringLiteral("Hello world"));
190     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
191     w.show();
192 
193     // test: call hide while hide animation still running
194     w.animatedHide();
195     if (delay) {
196         QTest::qWait(overlappingWaitingTime);
197     }
198     w.animatedHide();
199 
200     QTRY_VERIFY(!w.isHideAnimationRunning());
201     QCOMPARE(hideSignalsSpy.count(), 1);
202     CHECK_FULLY_NOT_VISIBLE
203 }
204 
testHideWithNotYetShownParent()205 void KMessageWidgetTest::testHideWithNotYetShownParent()
206 {
207     QWidget parent;
208     KMessageWidget w(QStringLiteral("Hello world"), &parent);
209     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
210 
211     // test: call hide while not yet visible
212     w.animatedHide();
213 
214     QTRY_VERIFY(!w.isHideAnimationRunning());
215     parent.show();
216 
217     QCOMPARE(hideSignalsSpy.count(), 1);
218     QVERIFY(!w.isVisible()); // Not CHECK_FULLY_NOT_VISIBLE because since it was never shown height is not what it would be otherwise
219 }
220 
testNonAnimatedShowAfterAnimatedHide()221 void KMessageWidgetTest::testNonAnimatedShowAfterAnimatedHide()
222 {
223     KMessageWidget w(QStringLiteral("Hello world"));
224     QSignalSpy hideSignalsSpy(&w, &KMessageWidget::hideAnimationFinished);
225 
226     w.show();
227     CHECK_FULLY_VISIBLE
228 
229     w.animatedHide();
230 
231     QTRY_VERIFY(!w.isHideAnimationRunning());
232 
233     QCOMPARE(hideSignalsSpy.count(), 1);
234     CHECK_FULLY_NOT_VISIBLE
235 
236     w.show();
237     CHECK_FULLY_VISIBLE
238 }
239