aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test_busyindicator.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/tests/test_busyindicator.cpp b/tests/test_busyindicator.cpp
new file mode 100644
index 0000000..3f267c7
--- /dev/null
+++ b/tests/test_busyindicator.cpp
@@ -0,0 +1,136 @@
+/*
+ * qtmaildir - a Qt6 mail client for notmuch-indexed Maildirs
+ * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <QtTest>
+
+#include "busyindicator.h"
+
+class TestBusyIndicator : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void itStartsIndeterminateAndHidden();
+ void itStaysHiddenInsideAShownParent();
+ void setProgressShowsARealFraction();
+ void aTotalOfZeroFallsBackToBusyRatherThanAnEmptyBar();
+ void itSwitchesBackFromDeterminateToIndeterminate();
+ void aValueOutsideTheRangeIsClamped();
+};
+
+void TestBusyIndicator::itStartsIndeterminateAndHidden()
+{
+ BusyIndicator indicator;
+
+ // setRange(0, 0) is what Qt reads as indeterminate, and it is the state
+ // the status bar's sync indicator lives in.
+ QCOMPARE(indicator.minimum(), 0);
+ QCOMPARE(indicator.maximum(), 0);
+ QVERIFY(!indicator.isDeterminate());
+}
+
+void TestBusyIndicator::itStaysHiddenInsideAShownParent()
+{
+ // The hidden-on-construction property needs a SHOWN PARENT to be
+ // observable at all, and both obvious probes measure nothing without one.
+ // Measured against a standalone Qt program: a parentless widget reports
+ // isVisible() false and isHidden() true whether or not hide() was ever
+ // called, so a mutation deleting the constructor's hide() survives both
+ // assertions. What differs is WA_WState_ExplicitShowHide, and the
+ // behaviour it produces appears only once a parent is shown, which is how
+ // MainWindow's status bar holds this widget.
+ QWidget parent;
+ BusyIndicator *indicator = new BusyIndicator(&parent);
+ parent.show();
+
+ QVERIFY2(!indicator->isBusy(),
+ "the indicator showed itself as soon as its parent appeared");
+
+ indicator->setBusy(true);
+ QVERIFY(indicator->isBusy());
+}
+
+void TestBusyIndicator::setProgressShowsARealFraction()
+{
+ BusyIndicator indicator;
+ indicator.setProgress(3, 10);
+
+ QVERIFY2(indicator.isDeterminate(),
+ "a bar given a total stayed in the indeterminate range");
+ QCOMPARE(indicator.maximum(), 10);
+ QCOMPARE(indicator.value(), 3);
+
+ // Showing a fraction means being visible. A caller that set progress and
+ // got a hidden widget would have to remember a second call.
+ QVERIFY(indicator.isBusy());
+}
+
+void TestBusyIndicator::aTotalOfZeroFallsBackToBusyRatherThanAnEmptyBar()
+{
+ // The trap this guards: setRange(0, 0) IS the indeterminate range, so a
+ // total of zero passed straight through would hand the caller an
+ // animating bar while it believed it had drawn an empty fraction. Making
+ // it explicitly busy is the honest reading of "no total known".
+ BusyIndicator indicator;
+ indicator.setProgress(0, 0);
+
+ QVERIFY(!indicator.isDeterminate());
+ QVERIFY2(indicator.isBusy(),
+ "a total of zero left the indicator hidden and silent");
+
+ indicator.setProgress(5, -1);
+ QVERIFY(!indicator.isDeterminate());
+ QVERIFY(indicator.isBusy());
+}
+
+void TestBusyIndicator::itSwitchesBackFromDeterminateToIndeterminate()
+{
+ // The send popup's whole reason for one widget rather than two: it drains
+ // a determinate bar through the undo countdown, then switches THE SAME
+ // widget to indeterminate when send_command starts and the duration stops
+ // being knowable. A setBusy() that left a stale range would keep drawing
+ // the countdown's last fraction.
+ BusyIndicator indicator;
+ indicator.setProgress(9, 10);
+ QVERIFY(indicator.isDeterminate());
+
+ indicator.setBusy(true);
+ QVERIFY2(!indicator.isDeterminate(),
+ "the bar kept the countdown's range after switching to busy");
+ QCOMPARE(indicator.maximum(), 0);
+ QVERIFY(indicator.isBusy());
+
+ indicator.setBusy(false);
+ QVERIFY(!indicator.isBusy());
+}
+
+void TestBusyIndicator::aValueOutsideTheRangeIsClamped()
+{
+ // A countdown driven by a timer can overshoot its own total by a tick.
+ // Qt leaves an out-of-range value unset rather than clamping, which shows
+ // the PREVIOUS fraction, so the bar would appear to stall near the end.
+ BusyIndicator indicator;
+ indicator.setProgress(50, 10);
+ QCOMPARE(indicator.value(), 10);
+
+ indicator.setProgress(-5, 10);
+ QCOMPARE(indicator.value(), 0);
+}
+
+QTEST_MAIN(TestBusyIndicator)
+#include "test_busyindicator.moc"