diff options
Diffstat (limited to 'tests/auto/qabstractbutton/tst_qabstractbutton.cpp')
-rw-r--r-- | tests/auto/qabstractbutton/tst_qabstractbutton.cpp | 718 |
1 files changed, 718 insertions, 0 deletions
diff --git a/tests/auto/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/qabstractbutton/tst_qabstractbutton.cpp new file mode 100644 index 0000000..5d4bd5b --- /dev/null +++ b/tests/auto/qabstractbutton/tst_qabstractbutton.cpp @@ -0,0 +1,718 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + + + +#include <qapplication.h> +#include <qpainter.h> +#include <qstyleoption.h> +#include <qkeysequence.h> +#include <qevent.h> +#include <qgridlayout.h> + + + +#include <qabstractbutton.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QAbstractButton : public QObject +{ + Q_OBJECT + +public: + tst_QAbstractButton(); + virtual ~tst_QAbstractButton(); + + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void setAutoRepeat_data(); + void setAutoRepeat(); + + void pressed(); + void released(); + void text(); + void setText(); + void icon(); + void setIcon(); + + void shortcut(); + void setShortcut(); + + void animateClick(); + + void isCheckable(); + void isDown(); + void setDown(); + void isChecked(); + void autoRepeat(); + void toggle(); + void clicked(); + void toggled(); + void isEnabled(); + void setEnabled(); +/* + void state(); + void group(); + void stateChanged(); +*/ + + void shortcutEvents(); + void stopRepeatTimer(); + + void keyNavigation(); + +protected slots: + void onClicked(); + void onToggled( bool on ); + void onPressed(); + void onReleased(); + void resetValues(); + +private: + uint click_count; + uint toggle_count; + uint press_count; + uint release_count; + + QAbstractButton *testWidget; +}; + +// QAbstractButton is an abstract class in 4.0 +class MyButton : public QAbstractButton +{ +public: + MyButton(QWidget *p = 0) : QAbstractButton(p) {} + void paintEvent(QPaintEvent *) + { + QPainter p(this); + QRect r = rect(); + p.fillRect(r, isDown() ? Qt::black : (isChecked() ? Qt::lightGray : Qt::white)); + p.setPen(isDown() ? Qt::white : Qt::black); + p.drawRect(r); + p.drawText(r, Qt::AlignCenter | Qt::TextShowMnemonic, text()); + if (hasFocus()) { + r.adjust(2, 2, -2, -2); + QStyleOptionFocusRect opt; + opt.rect = r; + opt.palette = palette(); + opt.state = QStyle::State_None; + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &p, this); +#ifdef Q_WS_MAC + p.setPen(Qt::red); + p.drawRect(r); +#endif + } + } + QSize sizeHint() const + { + QSize sh(8, 8); + if (!text().isEmpty()) + sh += fontMetrics().boundingRect(text()).size(); + return sh; + } + + void resetTimerEvents() { timerEvents = 0; } + int timerEventCount() const { return timerEvents; } + +private: + + int timerEvents; + + void timerEvent(QTimerEvent *event) + { + ++timerEvents; + QAbstractButton::timerEvent(event); + } +}; + +tst_QAbstractButton::tst_QAbstractButton() +{ +} + +tst_QAbstractButton::~tst_QAbstractButton() +{ +} + +void tst_QAbstractButton::initTestCase() +{ + testWidget = new MyButton(0); + testWidget->setObjectName("testObject"); + testWidget->resize( 200, 200 ); + testWidget->show(); + + connect( testWidget, SIGNAL(clicked()), this, SLOT(onClicked()) ); + connect( testWidget, SIGNAL(pressed()), this, SLOT(onPressed()) ); + connect( testWidget, SIGNAL(released()), this, SLOT(onReleased()) ); + connect( testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)) ); +} + +void tst_QAbstractButton::cleanupTestCase() +{ + delete testWidget; +} + +void tst_QAbstractButton::init() +{ + testWidget->setText("Test"); + testWidget->setEnabled( TRUE ); + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QKeySequence seq; + testWidget->setShortcut( seq ); + + toggle_count = 0; + press_count = 0; + release_count = 0; + click_count = 0; +} + +void tst_QAbstractButton::cleanup() +{ +} + +void tst_QAbstractButton::resetValues() +{ + toggle_count = 0; + press_count = 0; + release_count = 0; + click_count = 0; +} + +void tst_QAbstractButton::onClicked() +{ + click_count++; +} + +void tst_QAbstractButton::onToggled( bool /*on*/ ) +{ + toggle_count++; +} + +void tst_QAbstractButton::onPressed() +{ + press_count++; +} + +void tst_QAbstractButton::onReleased() +{ + release_count++; +} + +void tst_QAbstractButton::autoRepeat() +{ + DEPENDS_ON(" setAutoRepeat" ); +} + +void tst_QAbstractButton::setAutoRepeat_data() +{ + QTest::addColumn<int>("mode"); + QTest::newRow( "" ) << 0; + QTest::newRow( "" ) << 1; + QTest::newRow( "" ) << 2; + QTest::newRow( "" ) << 3; + QTest::newRow( "" ) << 4; + QTest::newRow( "" ) << 5; + QTest::newRow( "" ) << 6; +} + +#define REPEAT_DELAY 1000 + +int test_count = 0; +int last_mode = 0; + +void tst_QAbstractButton::setAutoRepeat() +{ + QFETCH( int, mode ); + + //FIXME: temp code to check that the test fails consistenly + //retest( 3 ); + + switch (mode) + { + case 0: + QVERIFY( !testWidget->isCheckable() ); + break; + case 1: + // check if we can toggle the mode + testWidget->setAutoRepeat( TRUE ); + QVERIFY( testWidget->autoRepeat() ); + + testWidget->setAutoRepeat( FALSE ); + QVERIFY( !testWidget->autoRepeat() ); + break; + case 2: + // check that the button is down if we press space and not in autorepeat + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QTest::keyPress( testWidget, Qt::Key_Space ); + + QTest::qWait( REPEAT_DELAY ); + + QVERIFY( release_count == 0 ); + QVERIFY( testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 1 ); + QVERIFY( click_count == 0 ); + + QTest::keyRelease( testWidget, Qt::Key_Space ); + QVERIFY( click_count == 1 ); + QVERIFY( release_count == 1 ); + break; + case 3: + // check that the button is down if we press space while in autorepeat + testWidget->setDown(false); + testWidget->setAutoRepeat(true); + QTest::keyPress(testWidget, Qt::Key_Space); + QTest::qWait(REPEAT_DELAY); + QVERIFY(testWidget->isDown()); + QTest::keyRelease(testWidget, Qt::Key_Space); + QVERIFY(release_count == press_count); + QVERIFY(toggle_count == 0); + QVERIFY(press_count == click_count); + QVERIFY(click_count > 1); + break; + case 4: + // check that pressing ENTER has no effect when autorepeat is FALSE + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QTest::keyPress( testWidget, Qt::Key_Enter ); + + QTest::qWait( REPEAT_DELAY ); + + QVERIFY( !testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 0 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); + QTest::keyRelease( testWidget, Qt::Key_Enter ); + + QVERIFY( click_count == 0 ); + break; + case 5: + // check that pressing ENTER has no effect when autorepeat is TRUE + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( TRUE ); + QTest::keyPress( testWidget, Qt::Key_Enter ); + + QTest::qWait( REPEAT_DELAY ); + + QVERIFY( !testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 0 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); + + QTest::keyRelease( testWidget, Qt::Key_Enter ); + + QVERIFY( click_count == 0 ); + break; + case 6: + // verify autorepeat is off by default. + MyButton tmp( 0); + tmp.setObjectName("tmp" ); + QVERIFY( !tmp.autoRepeat() ); + break; + } +} + +void tst_QAbstractButton::pressed() +{ + // pressed/released signals expected for a QAbstractButton + QTest::keyPress( testWidget, ' ' ); + QCOMPARE( press_count, (uint)1 ); +} + +void tst_QAbstractButton::released() +{ + // pressed/released signals expected for a QAbstractButton + QTest::keyPress( testWidget, ' ' ); + QTest::keyRelease( testWidget, ' ' ); + QCOMPARE( release_count, (uint)1 ); +} + +void tst_QAbstractButton::setText() +{ + testWidget->setText(""); + QCOMPARE( testWidget->text(), QString("") ); + testWidget->setText("simple"); + QCOMPARE( testWidget->text(), QString("simple") ); + testWidget->setText("&ersand"); + QCOMPARE( testWidget->text(), QString("&ersand") ); +#ifndef Q_WS_MAC // no mneonics on Mac. + QCOMPARE( testWidget->shortcut(), QKeySequence("ALT+A")); +#endif + testWidget->setText("te&st"); + QCOMPARE( testWidget->text(), QString("te&st") ); +#ifndef Q_WS_MAC // no mneonics on Mac. + QCOMPARE( testWidget->shortcut(), QKeySequence("ALT+S")); +#endif + testWidget->setText("foo"); + QCOMPARE( testWidget->text(), QString("foo") ); +#ifndef Q_WS_MAC // no mneonics on Mac. + QCOMPARE( testWidget->shortcut(), QKeySequence()); +#endif +} + +void tst_QAbstractButton::text() +{ + DEPENDS_ON( "setText" ); +} + +void tst_QAbstractButton::setIcon() +{ + const char *test1_xpm[] = { + "12 8 2 1", + ". c None", + "c c #ff0000", + ".........ccc", + "........ccc.", + ".......ccc..", + "ccc...ccc...", + ".ccc.ccc....", + "..ccccc.....", + "...ccc......", + "....c.......", + }; + + QPixmap p(test1_xpm); + testWidget->setIcon( p ); + QCOMPARE( testWidget->icon().pixmap(12, 8), p ); + + // Test for #14793 + + const char *test2_xpm[] = { + "12 8 2 1", + ". c None", + "c c #ff0000", + "ccc......ccc", + ".ccc....ccc.", + "..ccc..ccc..", + "....cc.cc...", + ".....ccc....", + "....cc.cc...", + "...ccc.ccc..", + "..ccc...ccc.", + }; + + int currentHeight = testWidget->height(); + int currentWidth = testWidget->width(); + + QPixmap p2( test2_xpm ); + for ( int a = 0; a<5; a++ ) + testWidget->setIcon( p2 ); + + QCOMPARE( testWidget->icon().pixmap(12, 8), p2 ); + + QCOMPARE( testWidget->height(), currentHeight ); + QCOMPARE( testWidget->width(), currentWidth ); +} + +void tst_QAbstractButton::icon() +{ + DEPENDS_ON( "setIcon" ); +} + +void tst_QAbstractButton::isEnabled() +{ + DEPENDS_ON( "setEnabled" ); +} + +void tst_QAbstractButton::setEnabled() +{ + testWidget->setEnabled( FALSE ); + QVERIFY( !testWidget->isEnabled() ); +// QTEST( testWidget, "disabled" ); + + testWidget->setEnabled( TRUE ); + QVERIFY( testWidget->isEnabled() ); +// QTEST( testWidget, "enabled" ); +} + +void tst_QAbstractButton::isCheckable() +{ + QVERIFY( !testWidget->isCheckable() ); +} + + +void tst_QAbstractButton::isDown() +{ + DEPENDS_ON( "setDown" ); +} + +void tst_QAbstractButton::setDown() +{ + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isDown() ); + + testWidget->setDown( TRUE ); + QTest::qWait(300); + QVERIFY( testWidget->isDown() ); + + testWidget->setDown( TRUE ); + + // add some debugging stuff + QWidget *grab = QWidget::keyboardGrabber(); + if (grab != 0 && grab != testWidget) + qDebug( "testWidget != keyboardGrabber" ); + grab = qApp->focusWidget(); + if (grab != 0 && grab != testWidget) + qDebug( "testWidget != focusWidget" ); + + QTest::keyClick( testWidget, Qt::Key_Escape ); + QVERIFY( !testWidget->isDown() ); +} + +void tst_QAbstractButton::isChecked() +{ + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isChecked() ); + + testWidget->setDown( TRUE ); + QVERIFY( !testWidget->isChecked() ); + + testWidget->setDown( FALSE ); + testWidget->toggle(); + QVERIFY( testWidget->isChecked() == testWidget->isCheckable() ); +} + +void tst_QAbstractButton::toggle() +{ + DEPENDS_ON( "toggled" ); +} + +void tst_QAbstractButton::toggled() +{ + testWidget->toggle(); + QVERIFY( toggle_count == 0 ); + + QTest::mousePress( testWidget, Qt::LeftButton ); + QVERIFY( toggle_count == 0 ); + QVERIFY( click_count == 0 ); + + QTest::mouseRelease( testWidget, Qt::LeftButton ); + QVERIFY( click_count == 1 ); +} + +void tst_QAbstractButton::shortcut() +{ + DEPENDS_ON( "setShortcut" ); +} + +void tst_QAbstractButton::setShortcut() +{ + QKeySequence seq( Qt::Key_A ); + testWidget->setShortcut( seq ); + + // must be active to get shortcuts + for (int i = 0; !testWidget->isActiveWindow() && i < 100; ++i) { + testWidget->activateWindow(); + QApplication::instance()->processEvents(); + QTest::qWait(100); + } + QVERIFY(testWidget->isActiveWindow()); + + QTest::keyClick( testWidget, 'A' ); + QTest::qWait(300); // Animate click takes time + QCOMPARE(click_count, (uint)1); + QCOMPARE(press_count, (uint)1); // Press is part of a click + QCOMPARE(release_count,(uint)1); // Release is part of a click + + QVERIFY( toggle_count == 0 ); + +// resetValues(); +// QTest::keyPress( testWidget, 'A' ); +// QTest::qWait(10000); +// QTest::keyRelease( testWidget, 'A' ); +// QCOMPARE(click_count, (uint)1); +// QCOMPARE(press_count, (uint)1); +// QCOMPARE(release_count,(uint)1); + +// qDebug() << click_count; + +} + +void tst_QAbstractButton::animateClick() +{ + testWidget->animateClick(); + QVERIFY( testWidget->isDown() ); + qApp->processEvents(); + QVERIFY( testWidget->isDown() ); + QTest::qWait(200); + qApp->processEvents(); + QVERIFY( !testWidget->isDown() ); +} + +void tst_QAbstractButton::clicked() +{ + DEPENDS_ON( "toggled" ); +} + +/* +void tst_QAbstractButton::group() +{ +} + +void tst_QAbstractButton::state() +{ +} + +void tst_QAbstractButton::stateChanged() +{ +} +*/ + +void tst_QAbstractButton::shortcutEvents() +{ + MyButton button; + QSignalSpy pressedSpy(&button, SIGNAL(pressed())); + QSignalSpy releasedSpy(&button, SIGNAL(released())); + QSignalSpy clickedSpy(&button, SIGNAL(clicked(bool))); + + for (int i = 0; i < 4; ++i) { + QKeySequence sequence; + QShortcutEvent event(sequence, false); + QApplication::sendEvent(&button, &event); + if (i < 2) + QTest::qWait(500); + } + + QTest::qWait(1000); // ensure animate timer is expired + + QCOMPARE(pressedSpy.count(), 3); + QCOMPARE(releasedSpy.count(), 3); + QCOMPARE(clickedSpy.count(), 3); +} + +void tst_QAbstractButton::stopRepeatTimer() +{ + MyButton button; + button.setAutoRepeat(true); + + // Mouse trigger case: + button.resetTimerEvents(); + QTest::mousePress(&button, Qt::LeftButton); + QTest::qWait(1000); + QVERIFY(button.timerEventCount() > 0); + + QTest::mouseRelease(&button, Qt::LeftButton); + button.resetTimerEvents(); + QTest::qWait(1000); + QCOMPARE(button.timerEventCount(), 0); + + // Key trigger case: + button.resetTimerEvents(); + QTest::keyPress(&button, Qt::Key_Space); + QTest::qWait(1000); + QVERIFY(button.timerEventCount() > 0); + + QTest::keyRelease(&button, Qt::Key_Space); + button.resetTimerEvents(); + QTest::qWait(1000); + QCOMPARE(button.timerEventCount(), 0); +} + +void tst_QAbstractButton::keyNavigation() +{ + QSKIP("Key navigation in QAbstractButton will be fixed/improved as part of task 194373", SkipSingle); + + QWidget widget; + QGridLayout *layout = new QGridLayout(&widget); + QAbstractButton *buttons[3][3]; + for(int y = 0; y < 3; y++) { + for(int x = 0; x < 3; x++) { + buttons[y][x] = new MyButton(&widget); + buttons[y][x]->setFocusPolicy(Qt::StrongFocus); + layout->addWidget(buttons[y][x], y, x); + } + } + + widget.show(); + qApp->setActiveWindow(&widget); + widget.activateWindow(); + QTest::qWait(30); + + buttons[1][1]->setFocus(); + QTest::qWait(400); + QVERIFY(buttons[1][1]->hasFocus()); + QTest::keyPress(buttons[1][1], Qt::Key_Up); + QTest::qWait(100); + QVERIFY(buttons[0][1]->hasFocus()); + QTest::keyPress(buttons[0][1], Qt::Key_Down); + QTest::qWait(100); + QVERIFY(buttons[1][1]->hasFocus()); + QTest::keyPress(buttons[1][1], Qt::Key_Left); + QTest::qWait(100); + QVERIFY(buttons[1][0]->hasFocus()); + QTest::keyPress(buttons[1][0], Qt::Key_Down); + QTest::qWait(100); + QVERIFY(buttons[2][0]->hasFocus()); + QTest::keyPress(buttons[2][0], Qt::Key_Right); + QTest::qWait(100); + QVERIFY(buttons[2][1]->hasFocus()); + QTest::keyPress(buttons[2][1], Qt::Key_Right); + QTest::qWait(100); + QVERIFY(buttons[2][2]->hasFocus()); + QTest::keyPress(buttons[2][2], Qt::Key_Up); + QTest::qWait(100); + QVERIFY(buttons[1][2]->hasFocus()); + QTest::keyPress(buttons[1][2], Qt::Key_Up); + QTest::qWait(100); + QVERIFY(buttons[0][2]->hasFocus()); + buttons[0][1]->hide(); + QTest::keyPress(buttons[0][2], Qt::Key_Left); + QTest::qWait(100); + QVERIFY(buttons[0][0]->hasFocus()); + + +} + +QTEST_MAIN(tst_QAbstractButton) +#include "tst_qabstractbutton.moc" |