Revision control
Copy as Markdown
// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qoaicommonglobal.h"
#include "client/qtapi.h"
#include "client/mixedapi.h"
#include "client/qobjectlike.h"
#include "client/qmetaenum.h"
#include <QtCore/qobject.h>
#include <QtCore/QMetaEnum>
#include <QtTest/qtest.h>
using namespace Qt::StringLiterals;
using namespace ReservedWords;
// If any reserved word is not escaped, the generated code will not compile:
// Qt keywords (emit, foreach, forever, signals, slots) would be expanded by the
// preprocessor and QObject methods (connect, disconnect) would clash with
// QObject's own methods. Compilation IS the primary verification.
// The runtime verifications below additionally confirm the exact identifier names.
class tst_ReservedWords : public QObject
{
Q_OBJECT
private Q_SLOTS:
void qtReservedWordsAsModelProperties();
void cppKeywordsAsModelProperties();
void qtReservedWordsAsOperationName();
void reservedEnumValues();
};
void tst_ReservedWords::qtReservedWordsAsModelProperties()
{
// Qt keywords: signals, slots, emit, foreach, forever
QObjectLike obj;
obj.setRSignals("test"_L1);
QCOMPARE(obj.getRSignals(), "test"_L1);
obj.setRSlots("test"_L1);
QCOMPARE(obj.getRSlots(), "test"_L1);
obj.setREmit(true);
QCOMPARE(obj.isREmit(), true);
obj.setRForeach("test"_L1);
QCOMPARE(obj.getRForeach(), "test"_L1);
obj.setRForever(false);
QCOMPARE(obj.isRForever(), false);
// QObject methods: connect, disconnect
obj.setRConnect("test"_L1);
QCOMPARE(obj.getRConnect(), "test"_L1);
obj.setRDisconnect("test"_L1);
QCOMPARE(obj.getRDisconnect(), "test"_L1);
}
void tst_ReservedWords::cppKeywordsAsModelProperties()
{
// class and struct: C++ keywords (handled by the upstream AbstractCppCodegen)
QObjectLike obj;
obj.setRClass("test"_L1);
QCOMPARE(obj.getRClass(), "test"_L1);
obj.setRStruct("test"_L1);
QCOMPARE(obj.getRStruct(), "test"_L1);
}
void tst_ReservedWords::qtReservedWordsAsOperationName()
{
const char *warningMsg = "Access manager destroyed while 1 requests were still in progress";
{
ReservedWords::QtApi api;
QTest::ignoreMessage(QtWarningMsg, warningMsg);
api.r_signals();
}
{
ReservedWords::QtApi api;
QObjectLike body;
body.setRSignals("test"_L1);
body.setRSlots("test"_L1);
QTest::ignoreMessage(QtWarningMsg, warningMsg);
api.r_connect("test"_L1, body);
}
{
ReservedWords::MixedApi mixedApi;
QTest::ignoreMessage(QtWarningMsg, warningMsg);
mixedApi.r_operator("test"_L1);
}
{
ReservedWords::QtApi api;
QTest::ignoreMessage(QtWarningMsg, warningMsg);
api.r_username();
}
}
void tst_ReservedWords::reservedEnumValues()
{
// All enum values are uppercased. Qt/C++ reserved words that are reserved only
// when lowercase (signals, class, int…) become safe after uppercasing, so they
// do not need the reserved-word prefix.
using E = ReservedWords::QMetaEnum::eQMetaEnum;
QVERIFY(E::SIGNALS != E::INVALID_VALUE_OPENAPI_GENERATED);
QVERIFY(E::SLOTS != E::INVALID_VALUE_OPENAPI_GENERATED);
QVERIFY(E::EMIT != E::INVALID_VALUE_OPENAPI_GENERATED);
QVERIFY(E::FOREACH != E::INVALID_VALUE_OPENAPI_GENERATED);
QVERIFY(E::FOREVER != E::INVALID_VALUE_OPENAPI_GENERATED);
QVERIFY(E::INT != E::INVALID_VALUE_OPENAPI_GENERATED);
QVERIFY(E::CLASS != E::INVALID_VALUE_OPENAPI_GENERATED);
// "null" is different: NULL is reserved when uppercase.
// So it should be escaped with the reserved-word prefix instead.
QVERIFY(E::r_NULL != E::INVALID_VALUE_OPENAPI_GENERATED);
}
QTEST_MAIN(tst_ReservedWords)
#include "tst_reservedwords.moc"