diff options
Diffstat (limited to 'tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp')
-rw-r--r-- | tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp | 118 |
1 files changed, 114 insertions, 4 deletions
diff --git a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp index f699d6816a..95748f46f7 100644 --- a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp +++ b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <jni.h> @@ -20,6 +20,7 @@ class tst_QJniEnvironment : public QObject Q_OBJECT private slots: + void init(); void jniEnv(); void javaVM(); void registerNativeMethods(); @@ -30,6 +31,14 @@ private slots: void findStaticField(); }; +void tst_QJniEnvironment::init() +{ + // Unless explicitly ignored to test error handling, warning messages + // in this test about a failure to look up a field, method, or class + // make the test fail. + QTest::failOnWarning(QRegularExpression("java.lang.NoSuch.*Error")); +} + void tst_QJniEnvironment::jniEnv() { QJniEnvironment env; @@ -59,17 +68,21 @@ void tst_QJniEnvironment::jniEnv() QVERIFY(!QJniEnvironment::checkAndClearExceptions(env.jniEnv())); // try to find a nonexistent class + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*")); QVERIFY(!env->FindClass("this/doesnt/Exist")); QVERIFY(QJniEnvironment::checkAndClearExceptions(env.jniEnv())); // try to find an existing class with QJniEnvironment QJniEnvironment env; QVERIFY(env.findClass("java/lang/Object")); + QVERIFY(env.findClass<jstring>()); // try to find a nonexistent class + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*")); QVERIFY(!env.findClass("this/doesnt/Exist")); // clear exception with member function + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*")); QVERIFY(!env->FindClass("this/doesnt/Exist")); QVERIFY(env.checkAndClearExceptions()); } @@ -98,14 +111,49 @@ static void callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) Q_UNUSED(env) registerNativesString = QJniObject(value).toString(); } -Q_JNI_DECLARE_NATIVE_METHOD(callbackFromJava); +Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJava); + +static void tediouslyLongNamed_callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) +{ + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); +} +Q_DECLARE_JNI_NATIVE_METHOD(tediouslyLongNamed_callbackFromJava, namedCallbackFromJava) static void callbackFromJavaNoCtor(JNIEnv *env, jobject /*thiz*/, jstring value) { Q_UNUSED(env) registerNativesString = QJniObject(value).toString(); } -Q_JNI_DECLARE_NATIVE_METHOD(callbackFromJavaNoCtor); +Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJavaNoCtor); + +class CallbackClass { +public: + static void memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(memberCallbackFromJava) + + static void tediouslyLongNamed_memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, + jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(tediouslyLongNamed_memberCallbackFromJava, + namedMemberCallbackFromJava) +}; + +namespace CallbackNamespace { + static void namespaceCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value) + { + Q_UNUSED(env) + registerNativesString = QJniObject(value).toString(); + } + Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(namespaceCallbackFromJava) +} void tst_QJniEnvironment::registerNativeMethods() { @@ -125,6 +173,63 @@ void tst_QJniEnvironment::registerNativeMethods() QVERIFY(registerNativesString == QStringLiteral("From Java: Qt")); } + // Named native function + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_METHOD(tediouslyLongNamed_callbackFromJava) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namedAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (named): Qt")); + } + + // Static class member as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(memberCallbackFromJava, CallbackClass) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "memberAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (member): Qt")); + } + + // Static named class member as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(tediouslyLongNamed_memberCallbackFromJava, + CallbackClass) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namedMemberAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (named member): Qt")); + } + + // Function generally just in namespace as callback + { + QVERIFY(env.registerNativeMethods(javaTestClass, { + Q_JNI_NATIVE_SCOPED_METHOD(namespaceCallbackFromJava, CallbackNamespace) + })); + + QJniObject::callStaticMethod<void>(javaTestClass, + "namespaceAppendJavaToString", + "(Ljava/lang/String;)V", + QtString.object<jstring>()); + QTest::qWait(200); + QVERIFY(registerNativesString == QStringLiteral("From Java (namespace): Qt")); + } + // No default constructor in class { QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, { @@ -145,7 +250,7 @@ static void intCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jint value) Q_UNUSED(env) registerNativeInteger = static_cast<int>(value); } -Q_JNI_DECLARE_NATIVE_METHOD(intCallbackFromJava); +Q_DECLARE_JNI_NATIVE_METHOD(intCallbackFromJava); void tst_QJniEnvironment::registerNativeMethodsByJclass() { @@ -180,6 +285,7 @@ void tst_QJniEnvironment::findMethod() QVERIFY(methodId != nullptr); // invalid signature + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*")); jmethodID invalid = env.findMethod(clazz, "unknown", "()I"); QVERIFY(invalid == nullptr); // check that all exceptions are already cleared @@ -206,8 +312,10 @@ void tst_QJniEnvironment::findStaticMethod() QCOMPARE(result, 123); // invalid method + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*")); jmethodID invalid = env.findStaticMethod(clazz, "unknown", "()I"); QVERIFY(invalid == nullptr); + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*")); invalid = env.findStaticMethod<jint>(clazz, "unknown"); QVERIFY(invalid == nullptr); // check that all exceptions are already cleared @@ -235,6 +343,7 @@ void tst_QJniEnvironment::findField() QVERIFY(value == 123); // invalid signature + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchFieldError: .*")); jfieldID invalidId = env.findField(clazz, "unknown", "I"); QVERIFY(invalidId == nullptr); // check that all exceptions are already cleared @@ -258,6 +367,7 @@ void tst_QJniEnvironment::findStaticField() QVERIFY(size == 321); // invalid signature + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchFieldError: .*")); jfieldID invalidId = env.findStaticField(clazz, "unknown", "I"); QVERIFY(invalidId == nullptr); // check that all exceptions are already cleared |