diff options
Diffstat (limited to 'tests/auto/corelib/global/qflags')
-rw-r--r-- | tests/auto/corelib/global/qflags/CMakeLists.txt | 17 | ||||
-rw-r--r-- | tests/auto/corelib/global/qflags/tst_qflags.cpp | 246 |
2 files changed, 215 insertions, 48 deletions
diff --git a/tests/auto/corelib/global/qflags/CMakeLists.txt b/tests/auto/corelib/global/qflags/CMakeLists.txt index 998834d619..8b01ea774f 100644 --- a/tests/auto/corelib/global/qflags/CMakeLists.txt +++ b/tests/auto/corelib/global/qflags/CMakeLists.txt @@ -1,13 +1,24 @@ -# Generated from qflags.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qflags Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qflags LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qflags SOURCES tst_qflags.cpp ) -## Scopes: -##################################################################### +qt_internal_add_test(tst_qflags_non_typesafe + SOURCES + tst_qflags.cpp + DEFINES + QFLAGS_TEST_NO_TYPESAFE_FLAGS +) diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 4b76a32c9a..d226e8d6b4 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -1,41 +1,30 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <QTest> +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifdef QFLAGS_TEST_NO_TYPESAFE_FLAGS +# ifdef QT_TYPESAFE_FLAGS +# undef QT_TYPESAFE_FLAGS +# endif +#else +# ifndef QT_TYPESAFE_FLAGS +# define QT_TYPESAFE_FLAGS +# endif +#endif -QT_WARNING_DISABLE_DEPRECATED +#include <QTest> class tst_QFlags: public QObject { Q_OBJECT private slots: + void boolCasts() const; + void operators() const; + void mixingDifferentEnums() const; void testFlag() const; void testFlagZeroFlag() const; void testFlagMultiBits() const; + void testFlags(); + void testAnyFlag(); void constExpr(); void signedness(); void classEnum(); @@ -44,6 +33,105 @@ private slots: void adl(); }; +void tst_QFlags::boolCasts() const +{ + // This tests that the operator overloading is sufficient so that common + // idioms involving flags -> bool casts work as expected: + + const Qt::Alignment nonNull = Qt::AlignCenter; + const Qt::Alignment null = {}; + + // basic premiss: + QVERIFY(bool(nonNull)); + QVERIFY(!bool(null)); + + // The rest is just checking that stuff compiles: + + // QVERIFY should compile: + QVERIFY(nonNull); + QVERIFY(!null); + + // ifs should compile: + if (null) QFAIL("Can't contextually convert QFlags to bool!"); + if (!nonNull) QFAIL("Missing operator! on QFlags (shouldn't be necessary)."); + + // ternary should compile: + QVERIFY(nonNull ? true : false); + QVERIFY(!null ? true : false); + + // logical operators should compile: + QVERIFY(nonNull && true); + QVERIFY(nonNull || false); + QVERIFY(!null && true); + QVERIFY(!null || false); + + // ... in both directions: + QVERIFY(true && nonNull); + QVERIFY(false || nonNull); + QVERIFY(true && !null); + QVERIFY(false || !null); + + // ... and mixed: + QVERIFY(null || nonNull); + QVERIFY(!(null && nonNull)); +} + +void tst_QFlags::operators() const +{ +#define CHECK(op, LHS, RHS, RES) \ + do { \ + QCOMPARE((LHS op RHS), (RES)); \ + QCOMPARE(( /*CTAD*/ QFlags(LHS) op RHS), (RES)); \ + QCOMPARE((LHS op QFlags(RHS)), (RES)); \ + QCOMPARE((QFlags(LHS) op QFlags(RHS)), (RES)); \ + QCOMPARE((QFlags(LHS) op ## = RHS), (RES)); \ + QCOMPARE((QFlags(LHS) op ## = QFlags(RHS)), (RES)); \ + } while (false) + + CHECK(|, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter); + CHECK(|, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter); + CHECK(&, Qt::AlignHCenter, Qt::AlignVCenter, Qt::Alignment()); + CHECK(&, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter); + CHECK(^, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter); + CHECK(^, Qt::AlignHCenter, Qt::AlignHCenter, Qt::Alignment()); +#undef CHECK +} + +void tst_QFlags::mixingDifferentEnums() const +{ +#define CHECK(op, LHS, RHS, RES) \ + /* LHS must be QFlags'able */ \ + do { \ + QCOMPARE((LHS op RHS), (RES)); \ + QCOMPARE((RHS op LHS), (RES)); \ + /*QCOMPARE(( / *CTAD* / QFlags(LHS) op RHS), (RES));*/ \ + /*QCOMPARE((QFlags(LHS) op ## = RHS), (RES));*/ \ + } while (false) + + // AlignmentFlags <-> TextFlags + { + CHECK(|, Qt::AlignCenter, Qt::TextSingleLine, 0x0184); + CHECK(&, Qt::AlignCenter, Qt::TextSingleLine, 0x0000); + CHECK(^, Qt::AlignCenter, Qt::TextSingleLine, 0x0184); + } + // QFlags<AlignmentFlags> <-> TextFlags + { +#ifndef QT_TYPESAFE_FLAGS // QTBUG-101344 + Qt::Alignment MyAlignCenter = Qt::AlignCenter; // convert enum to QFlags + CHECK(|, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned! + CHECK(&, MyAlignCenter, Qt::TextSingleLine, 0x0000U); // yes, unsigned! + CHECK(^, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned! +#endif + } + // TextElideMode <-> TextFlags + { + CHECK(|, Qt::ElideNone, Qt::TextSingleLine, 0x0103); + CHECK(&, Qt::ElideNone, Qt::TextSingleLine, 0x0000); + CHECK(^, Qt::ElideNone, Qt::TextSingleLine, 0x0103); + } +#undef CHECK +} + void tst_QFlags::testFlag() const { Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton; @@ -91,7 +179,64 @@ void tst_QFlags::testFlagMultiBits() const } } +void tst_QFlags::testFlags() +{ + using Int = Qt::TextInteractionFlags::Int; + constexpr Int Zero(0); + + Qt::TextInteractionFlags flags; + QCOMPARE(flags.toInt(), Zero); + QVERIFY(flags.testFlags(flags)); + QVERIFY(Qt::TextInteractionFlags::fromInt(Zero).testFlags(flags)); + QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse)); + QVERIFY(!flags.testFlags(Qt::TextSelectableByKeyboard)); + QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)); + QVERIFY(flags.testFlags(Qt::TextInteractionFlags::fromInt(Zero))); + QVERIFY(flags.testFlags(Qt::TextInteractionFlags(Qt::TextSelectableByMouse) & ~Qt::TextSelectableByMouse)); + + flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard; + QVERIFY(flags.toInt() != Zero); + QVERIFY(flags.testFlags(flags)); + QVERIFY(flags.testFlags(Qt::TextSelectableByMouse)); + QVERIFY(flags.testFlags(Qt::TextSelectableByKeyboard)); + QVERIFY(flags.testFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse)); + QVERIFY(!flags.testFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse | Qt::TextEditable)); + QVERIFY(!flags.testFlags(Qt::TextInteractionFlags())); + QVERIFY(!flags.testFlags(Qt::TextInteractionFlags::fromInt(Zero))); + QVERIFY(!flags.testFlags(Qt::TextEditable)); + QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse | Qt::TextEditable)); +} + +void tst_QFlags::testAnyFlag() +{ + Qt::TextInteractionFlags flags; + QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction)); + QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByMouse)); + QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByKeyboard)); + QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)); + QVERIFY(!flags.testAnyFlag(Qt::TextEditorInteraction)); + QVERIFY(!flags.testAnyFlag(Qt::TextBrowserInteraction)); + + flags = Qt::TextSelectableByMouse; + QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction)); + QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse)); + QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByKeyboard)); + QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)); + QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction)); + QVERIFY(flags.testAnyFlag(Qt::TextBrowserInteraction)); + + flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard; + QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction)); + QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse)); + QVERIFY(flags.testAnyFlags(Qt::TextSelectableByKeyboard)); + QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)); + QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction)); + QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction)); + QVERIFY(flags.testAnyFlag(Qt::TextBrowserInteraction)); +} + template <unsigned int N, typename T> bool verifyConstExpr(T n) { return n == N; } +template <unsigned int N, typename T> bool verifyConstExpr(QFlags<T> n) { return n.toInt() == N; } constexpr Qt::MouseButtons testRelaxedConstExpr() { @@ -106,25 +251,32 @@ constexpr Qt::MouseButtons testRelaxedConstExpr() void tst_QFlags::constExpr() { Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton; - switch (btn) { - case Qt::LeftButton: QVERIFY(false); break; - case Qt::RightButton: QVERIFY(false); break; - case int(Qt::LeftButton | Qt::RightButton): QVERIFY(true); break; - default: QVERIFY(false); + switch (btn.toInt()) { + case Qt::LeftButton: QVERIFY(false); break; + case Qt::RightButton: QVERIFY(false); break; + case (Qt::LeftButton | Qt::RightButton).toInt(): QVERIFY(true); break; + default: QFAIL(qPrintable(QStringLiteral("Unexpected button: %1").arg(btn.toInt()))); } - QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) & Qt::LeftButton)>(Qt::LeftButton)); - QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) & Qt::MiddleButton)>(0)); - QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) | Qt::MiddleButton)>(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton)); - QVERIFY(verifyConstExpr<uint(~(Qt::LeftButton | Qt::RightButton))>(~(Qt::LeftButton | Qt::RightButton))); - QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::LeftButton) ^ Qt::RightButton)>(Qt::LeftButton ^ Qt::RightButton)); - QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(0))>(0)); - QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::RightButton) & 0xff)>(Qt::RightButton)); - QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::RightButton) | 0xff)>(0xff)); +#define VERIFY_CONSTEXPR(expression, expected) \ + QVERIFY(verifyConstExpr<(expression).toInt()>(expected)) + + VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) & Qt::LeftButton, Qt::LeftButton); + VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) & Qt::MiddleButton, 0); + VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) | Qt::MiddleButton, Qt::LeftButton | Qt::RightButton | Qt::MiddleButton); + VERIFY_CONSTEXPR(~(Qt::LeftButton | Qt::RightButton), ~(Qt::LeftButton | Qt::RightButton)); + VERIFY_CONSTEXPR(Qt::MouseButtons(Qt::LeftButton) ^ Qt::RightButton, Qt::LeftButton ^ Qt::RightButton); + VERIFY_CONSTEXPR(Qt::MouseButtons(0), 0); +#ifndef QT_TYPESAFE_FLAGS + QVERIFY(verifyConstExpr<(Qt::MouseButtons(Qt::RightButton) & 0xff)>(Qt::RightButton)); + QVERIFY(verifyConstExpr<(Qt::MouseButtons(Qt::RightButton) | 0xff)>(0xff)); +#endif QVERIFY(!verifyConstExpr<Qt::RightButton>(~Qt::MouseButtons(Qt::LeftButton))); - QVERIFY(verifyConstExpr<uint(testRelaxedConstExpr())>(Qt::MiddleButton)); + VERIFY_CONSTEXPR(testRelaxedConstExpr(), Qt::MiddleButton); + +#undef VERIFY_CONSTEXPR } void tst_QFlags::signedness() @@ -149,7 +301,7 @@ Q_DECLARE_FLAGS( MyStrictNoOpFlags, MyStrictNoOpEnum ) static_assert( !QTypeInfo<MyStrictFlags>::isComplex ); static_assert( QTypeInfo<MyStrictFlags>::isRelocatable ); -static_assert( !QTypeInfo<MyStrictFlags>::isPointer ); +static_assert( !std::is_pointer_v<MyStrictFlags> ); void tst_QFlags::classEnum() { @@ -175,11 +327,14 @@ void tst_QFlags::classEnum() QVERIFY(!f0); +#ifndef QT_TYPESAFE_FLAGS QCOMPARE(f3 & int(1), 1); QCOMPARE(f3 & uint(1), 1); +#endif QCOMPARE(f3 & MyStrictEnum::StrictOne, 1); MyStrictFlags aux; +#ifndef QT_TYPESAFE_FLAGS aux = f3; aux &= int(1); QCOMPARE(aux, 1); @@ -187,6 +342,7 @@ void tst_QFlags::classEnum() aux = f3; aux &= uint(1); QCOMPARE(aux, 1); +#endif aux = f3; aux &= MyStrictEnum::StrictOne; @@ -319,7 +475,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( MyFlags ) static_assert( !QTypeInfo<MyFlags>::isComplex ); static_assert( QTypeInfo<MyFlags>::isRelocatable ); -static_assert( !QTypeInfo<MyFlags>::isPointer ); +static_assert( !std::is_pointer_v<MyFlags> ); QTEST_MAIN(tst_QFlags) #include "tst_qflags.moc" |