Files
samiandClaude Sonnet 5 2959b0f707 gui: real RTL + no-download-logic checks; split into velox-gui-lib
Follow-up hardening after a review noted the RTL "check" verified nothing
(a .ts stub that no test loads), matching a session-wide pattern of
checks written against what should be true rather than what would break.

- Split the non-main() code into velox-gui-lib (STATIC) so tests link the
  real widgets/models, not a reimplementation.
- tst_rtl: builds the real MainWindow, flips layoutDirection, asserts the
  direction propagates to the central widget AND that the offline-banner
  QHBoxLayout actually mirrors (label x-position LTR vs RTL differs by
  >100px). Verified it fails when the banner is pinned LtR.
- gui_no_download_logic: a ctest that greps gui/src for curl_*/pwrite/
  sqlite/QSqlDatabase/QNetworkAccessManager and fails on a hit — CLAUDE.md
  §3 as an executable check. Verified it fails when a curl_ token is added.
- Still uncovered (noted, not claimed): that the translation catalogue
  loads and the right context/strings resolve at runtime.

Not covered here because the files are PKG/QA-owned: tools/bootstrap.sh
ships a package name that does not exist on 26.04 (libqt6svg6-dev; the
real one is qt6-svg-dev), and --check validates pkg-config outcomes
rather than the apt names it would install. Both, plus the same name in
AGENT-PKG-QA.md and the README, are written up apply-ready in
gui/docs/pkg-qa-requests-m1.md.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016Ne28kx4VreeBWZv82Nksd
2026-09-10 01:12:06 +04:00

71 lines
2.4 KiB
C++

// RTL layout test. Lane GUI.
//
// The GUI DoD asks for "a stub Arabic .ts proves the RTL layout survives". A .ts file on
// its own proves nothing — this is the check with teeth: build the real main window, flip
// the layout direction, and assert (a) the direction propagates to the children and
// (b) a layout we own actually mirrors, by comparing a widget's position LTR vs RTL.
#include <QApplication>
#include <QLabel>
#include <QWidget>
#include <QtTest>
#include "mainwindow/MainWindow.hpp"
#include "rpc/RpcClient.hpp"
using velox::gui::MainWindow;
namespace {
int settledLeftOf(QWidget *w) {
QCoreApplication::processEvents();
QTest::qWait(30);
QCoreApplication::processEvents();
return w->mapTo(w->window(), QPoint(0, 0)).x();
}
} // namespace
class TstRtl : public QObject {
Q_OBJECT
private slots:
void directionPropagatesAndLayoutMirrors();
};
void TstRtl::directionPropagatesAndLayoutMirrors() {
velox::gui::rpc::RpcClient client(QStringLiteral("/nonexistent/velox-rtl-test.sock"));
MainWindow window(&client); // never started — the window must build without a daemon
window.resize(900, 500);
window.setLayoutDirection(Qt::LeftToRight);
window.show();
auto *bannerLabel = window.findChild<QLabel *>(QStringLiteral("offlineBannerLabel"));
QVERIFY2(bannerLabel != nullptr, "offline banner label not found");
QVERIFY2(bannerLabel->isVisible(), "offline banner should be visible while disconnected");
const int leftLtr = settledLeftOf(bannerLabel);
window.setLayoutDirection(Qt::RightToLeft);
// Propagation: the window and its central widget must both flip.
QCOMPARE(window.layoutDirection(), Qt::RightToLeft);
QVERIFY2(window.centralWidget() != nullptr, "no central widget");
QCOMPARE(window.centralWidget()->layoutDirection(), Qt::RightToLeft);
const int leftRtl = settledLeftOf(bannerLabel);
// The banner is [label][stretch] in a QHBoxLayout we build ourselves. LTR pins the
// label near x=0; RTL must push it to the right by (roughly) the free space. If the
// layout ignored direction this delta would be ~0.
QVERIFY2(leftRtl - leftLtr > 100,
qPrintable(QStringLiteral("offline banner did not mirror under RTL: "
"label x LTR=%1 RTL=%2")
.arg(leftLtr)
.arg(leftRtl)));
}
QTEST_MAIN(TstRtl)
#include "tst_rtl.moc"