/** * @file test_ltswidgets_qt6.cpp * @brief Tests für LtsWidgets Qt6-Migration * * Tests verify Qt6 API compatibility changes: * 1. QRandomGenerator usage (replacing qrand()) * 2. Signal/slot connections with Qt6 signatures * 3. QWheelEvent angleDelta() usage * 4. QStyleOption::initFrom() usage */ #include #include #include #include #include #include #include // Ensure QApplication is initialized for widget tests static bool appInitialized = false; static void ensureAppInitialized() { if (!appInitialized) { static int argc = 1; static char* argv[] = {(char*)"test_ltswidgets_qt6", nullptr}; static QApplication app(argc, argv); appInitialized = true; } } // Test 1: QRandomGenerator bounded generation (used in lts_tab_widget.cpp) TEST(LtsWidgetsQt6, QRandomGeneratorBounded) { auto* generator = QRandomGenerator::global(); ASSERT_NE(generator, nullptr); // Test multiple bounded calls to ensure stability for (int i = 0; i < 100; ++i) { int value = generator->bounded(10); EXPECT_GE(value, 0); EXPECT_LT(value, 10); } } // Test 2: QRandomGenerator produces different values TEST(LtsWidgetsQt6, QRandomGeneratorVariation) { auto* generator = QRandomGenerator::global(); QVector values; for (int i = 0; i < 50; ++i) { values.append(generator->bounded(1000)); } // Check that we get some variation (not all same value) bool hasDifferent = false; for (int i = 1; i < values.size(); ++i) { if (values[i] != values[0]) { hasDifferent = true; break; } } EXPECT_TRUE(hasDifferent); } // Test 3: QRandomGenerator seeded reproducibility TEST(LtsWidgetsQt6, QRandomGeneratorSeeded) { QRandomGenerator gen1(12345); QRandomGenerator gen2(12345); // Same seed should produce same sequence for (int i = 0; i < 10; ++i) { EXPECT_EQ(gen1.bounded(1000), gen2.bounded(1000)); } } // Test 4: QComboBox currentTextChanged signal (Qt6 compatible) // This tests the signal used in lts_text_editor.cpp TEST(LtsWidgetsQt6, QComboBoxCurrentTextChangedSignal) { ensureAppInitialized(); QComboBox comboBox; comboBox.addItem(QStringLiteral("Option1")); comboBox.addItem(QStringLiteral("Option2")); comboBox.addItem(QStringLiteral("Option3")); bool signalReceived = false; QString receivedText; QObject::connect(&comboBox, &QComboBox::currentTextChanged, [&signalReceived, &receivedText](const QString& text) { signalReceived = true; receivedText = text; }); comboBox.setCurrentIndex(1); EXPECT_TRUE(signalReceived); EXPECT_EQ(receivedText, QStringLiteral("Option2")); } // Test 5: QComboBox activated signal with int parameter (Qt6) // Note: activated signal is only emitted on user interaction, not on setCurrentIndex TEST(LtsWidgetsQt6, QComboBoxActivatedIntSignal) { ensureAppInitialized(); QComboBox comboBox; comboBox.addItem(QStringLiteral("First")); comboBox.addItem(QStringLiteral("Second")); comboBox.addItem(QStringLiteral("Third")); bool signalReceived = false; int receivedIndex = -1; // Connect using Qt6 syntax - activated emits int index QObject::connect(&comboBox, QOverload::of(&QComboBox::activated), [&signalReceived, &receivedIndex](int index) { signalReceived = true; receivedIndex = index; }); // Simulate user interaction by emitting the signal manually // (setCurrentIndex does not trigger activated signal) QMetaObject::invokeMethod(&comboBox, "activated", Qt::QueuedConnection, Q_ARG(int, 2)); QCoreApplication::processEvents(); // Verify the connection works with int parameter EXPECT_TRUE(signalReceived); EXPECT_EQ(receivedIndex, 2); } // Test 6: QStyleOption::initFrom() (Qt6 replacement for init()) // This tests the API used in lts_notification_box.cpp TEST(LtsWidgetsQt6, QStyleOptionInitFrom) { ensureAppInitialized(); QPushButton button(QStringLiteral("Test")); button.resize(100, 30); button.setEnabled(true); QStyleOption opt; opt.initFrom(&button); // Verify initFrom sets up the option correctly // State_Enabled should be set (among other states) EXPECT_TRUE(opt.state & QStyle::State_Enabled); EXPECT_FALSE(opt.rect.isNull()); } // Test 7: QStyleOption multiple widgets TEST(LtsWidgetsQt6, QStyleOptionInitFromMultipleWidgets) { ensureAppInitialized(); QPushButton button1(QStringLiteral("Btn1")); QPushButton button2(QStringLiteral("Btn2")); button1.setEnabled(true); button2.setEnabled(false); QStyleOption opt1; opt1.initFrom(&button1); QStyleOption opt2; opt2.initFrom(&button2); // Verify different widget states are captured EXPECT_TRUE(opt1.state & QStyle::State_Enabled); EXPECT_FALSE(opt2.state & QStyle::State_Enabled); } // Test 8: QWheelEvent angleDelta() availability // This verifies the API used in lts_date_time_edit_p.cpp TEST(LtsWidgetsQt6, QWheelEventAngleDelta) { ensureAppInitialized(); QPoint pos(100, 100); QPoint globalPos(200, 200); QPoint pixelDelta(0, 0); QPoint angleDelta(0, 120); // Standard wheel step QWheelEvent wheelEvent(pos, globalPos, pixelDelta, angleDelta, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); // Verify angleDelta() is accessible and returns correct value QPoint delta = wheelEvent.angleDelta(); EXPECT_EQ(delta.y(), 120); EXPECT_EQ(delta.x(), 0); } // Test 9: QWheelEvent negative angleDelta TEST(LtsWidgetsQt6, QWheelEventNegativeAngleDelta) { ensureAppInitialized(); QPoint pos(100, 100); QPoint globalPos(200, 200); QPoint pixelDelta(0, 0); QPoint angleDelta(0, -120); // Scroll down QWheelEvent wheelEvent(pos, globalPos, pixelDelta, angleDelta, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QPoint delta = wheelEvent.angleDelta(); EXPECT_EQ(delta.y(), -120); // Test the logic used in lts_date_time_edit_p.cpp bool isUp = delta.y() > 0; EXPECT_FALSE(isUp); } // Test 10: QWheelEvent angleDelta direction detection TEST(LtsWidgetsQt6, QWheelEventDirectionDetection) { ensureAppInitialized(); // Simulate wheel up (positive delta) QPoint angleDeltaUp(0, 120); QWheelEvent wheelUp(QPoint(0, 0), QPoint(0, 0), QPoint(0, 0), angleDeltaUp, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); EXPECT_TRUE(wheelUp.angleDelta().y() > 0); // Simulate wheel down (negative delta) QPoint angleDeltaDown(0, -120); QWheelEvent wheelDown(QPoint(0, 0), QPoint(0, 0), QPoint(0, 0), angleDeltaDown, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); EXPECT_FALSE(wheelDown.angleDelta().y() > 0); }