summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-04-23 16:43:35 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2022-05-13 18:13:49 +0200
commit601dbd64993fcbbb2ce6aaa95ef153ffd4f852b9 (patch)
tree9218bc36e0be5a21a5c88e21f58c7c914feb78a4 /tests/auto
parentb9c55b5b9e983e446695f471aed1cdf14e14c88e (diff)
Add variadic template overloads for QJniObject/Environment methods
This allows the compiler to deduce the template arguments based on the provided method parameters, which we can then pass to the methodSignature and fieldSignature helpers to generate the signature string completely at compile time. Since we can't partially specialize template member functions, replace the specializations for void methods with compile-time-if branches in the general templates. This variadic template now prevents implicit conversion from the LiteralStorage types to const char* signatures, so catch the case where such a type ends up in the parameter list. Due to overload resolution rules for constructors, we need to explicitly disable the constructor if any of the arguments is a string literal type, as we have to keep the old C-style variadic function working for such calls. Add variations that use the variadic templates to the unit tests. Change-Id: I8734664b38bae932369462330a9a03302254c33c Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp14
-rw-r--r--tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp153
2 files changed, 150 insertions, 17 deletions
diff --git a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp
index 8cf207fc3a..b3f420fd45 100644
--- a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp
+++ b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp
@@ -202,6 +202,10 @@ void tst_QJniEnvironment::findMethod()
jmethodID methodId = env.findMethod(clazz, "toString", "()Ljava/lang/String;");
QVERIFY(methodId != nullptr);
+ // existing method
+ methodId = env.findMethod<jstring>(clazz, "toString");
+ QVERIFY(methodId != nullptr);
+
// invalid signature
jmethodID invalid = env.findMethod(clazz, "unknown", "()I");
QVERIFY(invalid == nullptr);
@@ -219,6 +223,10 @@ void tst_QJniEnvironment::findStaticMethod()
jmethodID staticMethodId = env.findStaticMethod(clazz, "parseInt", "(Ljava/lang/String;)I");
QVERIFY(staticMethodId != nullptr);
+ // existing method
+ staticMethodId = env.findStaticMethod<jint, jstring>(clazz, "parseInt");
+ QVERIFY(staticMethodId != nullptr);
+
QJniObject parameter = QJniObject::fromString("123");
jint result = QJniObject::callStaticMethod<jint>(clazz, staticMethodId,
parameter.object<jstring>());
@@ -227,6 +235,8 @@ void tst_QJniEnvironment::findStaticMethod()
// invalid method
jmethodID invalid = env.findStaticMethod(clazz, "unknown", "()I");
QVERIFY(invalid == nullptr);
+ invalid = env.findStaticMethod<jint>(clazz, "unknown");
+ QVERIFY(invalid == nullptr);
// check that all exceptions are already cleared
QVERIFY(!env.checkAndClearExceptions());
}
@@ -240,6 +250,8 @@ void tst_QJniEnvironment::findField()
// valid field
jfieldID validId = env.findField(clazz, "INT_FIELD", "I");
QVERIFY(validId != nullptr);
+ validId = env.findField<jint>(clazz, "INT_FIELD");
+ QVERIFY(validId != nullptr);
jmethodID constructorId = env.findMethod(clazz, "<init>", "()V");
QVERIFY(constructorId != nullptr);
@@ -265,6 +277,8 @@ void tst_QJniEnvironment::findStaticField()
// valid field
jfieldID validId = env.findStaticField(clazz, "S_INT_FIELD", "I");
QVERIFY(validId != nullptr);
+ validId = env.findStaticField<jint>(clazz, "S_INT_FIELD");
+ QVERIFY(validId != nullptr);
int size = env->GetStaticIntField(clazz, validId);
QVERIFY(!env.checkAndClearExceptions());
diff --git a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
index 4c0d9e1e6e..669f31650e 100644
--- a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
+++ b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
@@ -167,6 +167,13 @@ void tst_QJniObject::ctor()
}
{
+ QJniObject string = QJniObject::fromString(QLatin1String("Hello, Java"));
+ QJniObject object("java/lang/String", string.object<jstring>());
+ QVERIFY(object.isValid());
+ QCOMPARE(string.toString(), object.toString());
+ }
+
+ {
QJniEnvironment env;
jclass javaStringClass = env->FindClass("java/lang/String");
QJniObject string(javaStringClass);
@@ -182,6 +189,16 @@ void tst_QJniObject::ctor()
QVERIFY(stringCpy.isValid());
QCOMPARE(qString, stringCpy.toString());
}
+
+ {
+ QJniEnvironment env;
+ const QString qString = QLatin1String("Hello, Java");
+ jclass javaStringClass = env->FindClass("java/lang/String");
+ QJniObject string = QJniObject::fromString(qString);
+ QJniObject stringCpy(javaStringClass, string.object<jstring>());
+ QVERIFY(stringCpy.isValid());
+ QCOMPARE(qString, stringCpy.toString());
+ }
}
void tst_QJniObject::callMethodTest()
@@ -194,9 +211,12 @@ void tst_QJniObject::callMethodTest()
const jboolean isEmpty = jString1.callMethod<jboolean>("isEmpty");
QVERIFY(!isEmpty);
- const jint ret = jString1.callMethod<jint>("compareToIgnoreCase",
- "(Ljava/lang/String;)I",
- jString2.object<jstring>());
+ jint ret = jString1.callMethod<jint>("compareToIgnoreCase",
+ "(Ljava/lang/String;)I",
+ jString2.object<jstring>());
+ QVERIFY(0 == ret);
+
+ ret = jString1.callMethod<jint>("compareToIgnoreCase", jString2.object<jstring>());
QVERIFY(0 == ret);
}
@@ -219,6 +239,10 @@ void tst_QJniObject::callObjectMethodTest()
"(II)Ljava/lang/String;",
0, 4);
QCOMPARE(subString.toString(), qString.mid(0, 4));
+
+ subString = jString.callObjectMethod<jstring>("substring", 0, 4);
+ QCOMPARE(subString.toString(), qString.mid(0, 4));
+
}
void tst_QJniObject::stringConvertionTest()
@@ -276,6 +300,16 @@ void tst_QJniObject::callStaticObjectMethodClassName()
QString returnedString = returnValue.toString();
QCOMPARE(returnedString, QString::fromLatin1("test format"));
+
+ returnValue = QJniObject::callStaticObjectMethod<jstring>("java/lang/String",
+ "format",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+
+ returnedString = returnValue.toString();
+
+ QCOMPARE(returnedString, QString::fromLatin1("test format"));
}
void tst_QJniObject::callStaticObjectMethod()
@@ -297,6 +331,16 @@ void tst_QJniObject::callStaticObjectMethod()
QString returnedString = returnValue.toString();
QCOMPARE(returnedString, QString::fromLatin1("test format"));
+
+ returnValue = QJniObject::callStaticObjectMethod<jstring>(cls,
+ "format",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+
+ returnedString = returnValue.toString();
+
+ QCOMPARE(returnedString, QString::fromLatin1("test format"));
}
void tst_QJniObject::callStaticObjectMethodById()
@@ -336,6 +380,9 @@ void tst_QJniObject::callStaticBooleanMethod()
"(Ljava/lang/String;)Z",
parameter.object<jstring>());
QVERIFY(b);
+
+ b = QJniObject::callStaticMethod<jboolean>(cls, "parseBoolean", parameter.object<jstring>());
+ QVERIFY(b);
}
{
@@ -347,6 +394,9 @@ void tst_QJniObject::callStaticBooleanMethod()
"(Ljava/lang/String;)Z",
parameter.object<jstring>());
QVERIFY(!b);
+
+ b = QJniObject::callStaticMethod<jboolean>(cls, "parseBoolean", parameter.object<jstring>());
+ QVERIFY(!b);
}
}
@@ -387,6 +437,10 @@ void tst_QJniObject::callStaticBooleanMethodClassName()
"(Ljava/lang/String;)Z",
parameter.object<jstring>());
QVERIFY(b);
+ b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
+ "parseBoolean",
+ parameter.object<jstring>());
+ QVERIFY(b);
}
{
@@ -398,6 +452,10 @@ void tst_QJniObject::callStaticBooleanMethodClassName()
"(Ljava/lang/String;)Z",
parameter.object<jstring>());
QVERIFY(!b);
+ b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
+ "parseBoolean",
+ parameter.object<jstring>());
+ QVERIFY(!b);
}
}
@@ -408,7 +466,6 @@ void tst_QJniObject::callStaticByteMethodClassName()
jbyte returnValue = QJniObject::callStaticMethod<jbyte>("java/lang/Byte",
"parseByte",
- "(Ljava/lang/String;)B",
parameter.object<jstring>());
QCOMPARE(returnValue, jbyte(number.toInt()));
}
@@ -424,7 +481,6 @@ void tst_QJniObject::callStaticByteMethod()
jbyte returnValue = QJniObject::callStaticMethod<jbyte>(cls,
"parseByte",
- "(Ljava/lang/String;)B",
parameter.object<jstring>());
QCOMPARE(returnValue, jbyte(number.toInt()));
}
@@ -452,7 +508,6 @@ void tst_QJniObject::callStaticIntMethodClassName()
jint returnValue = QJniObject::callStaticMethod<jint>("java/lang/Integer",
"parseInt",
- "(Ljava/lang/String;)I",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toInt());
}
@@ -469,7 +524,6 @@ void tst_QJniObject::callStaticIntMethod()
jint returnValue = QJniObject::callStaticMethod<jint>(cls,
"parseInt",
- "(Ljava/lang/String;)I",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toInt());
}
@@ -494,7 +548,6 @@ void tst_QJniObject::callStaticCharMethodClassName()
{
jchar returnValue = QJniObject::callStaticMethod<jchar>("java/lang/Character",
"toUpperCase",
- "(C)C",
jchar('a'));
QCOMPARE(returnValue, jchar('A'));
}
@@ -508,7 +561,6 @@ void tst_QJniObject::callStaticCharMethod()
jchar returnValue = QJniObject::callStaticMethod<jchar>(cls,
"toUpperCase",
- "(C)C",
jchar('a'));
QCOMPARE(returnValue, jchar('A'));
}
@@ -533,7 +585,6 @@ void tst_QJniObject::callStaticDoubleMethodClassName ()
jdouble returnValue = QJniObject::callStaticMethod<jdouble>("java/lang/Double",
"parseDouble",
- "(Ljava/lang/String;)D",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toDouble());
}
@@ -550,7 +601,6 @@ void tst_QJniObject::callStaticDoubleMethod()
jdouble returnValue = QJniObject::callStaticMethod<jdouble>(cls,
"parseDouble",
- "(Ljava/lang/String;)D",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toDouble());
}
@@ -579,7 +629,6 @@ void tst_QJniObject::callStaticFloatMethodClassName()
jfloat returnValue = QJniObject::callStaticMethod<jfloat>("java/lang/Float",
"parseFloat",
- "(Ljava/lang/String;)F",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toFloat());
}
@@ -596,7 +645,6 @@ void tst_QJniObject::callStaticFloatMethod()
jfloat returnValue = QJniObject::callStaticMethod<jfloat>(cls,
"parseFloat",
- "(Ljava/lang/String;)F",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toFloat());
}
@@ -624,7 +672,6 @@ void tst_QJniObject::callStaticShortMethodClassName()
jshort returnValue = QJniObject::callStaticMethod<jshort>("java/lang/Short",
"parseShort",
- "(Ljava/lang/String;)S",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toShort());
}
@@ -641,7 +688,6 @@ void tst_QJniObject::callStaticShortMethod()
jshort returnValue = QJniObject::callStaticMethod<jshort>(cls,
"parseShort",
- "(Ljava/lang/String;)S",
parameter.object<jstring>());
QCOMPARE(returnValue, number.toShort());
}
@@ -669,7 +715,6 @@ void tst_QJniObject::callStaticLongMethodClassName()
jlong returnValue = QJniObject::callStaticMethod<jlong>("java/lang/Long",
"parseLong",
- "(Ljava/lang/String;)J",
parameter.object<jstring>());
QCOMPARE(returnValue, jlong(number.toLong()));
}
@@ -685,7 +730,6 @@ void tst_QJniObject::callStaticLongMethod()
jlong returnValue = QJniObject::callStaticMethod<jlong>(cls,
"parseLong",
- "(Ljava/lang/String;)J",
parameter.object<jstring>());
QCOMPARE(returnValue, jlong(number.toLong()));
}
@@ -1044,9 +1088,15 @@ void tst_QJniObject::templateApiCheck()
1,
true,
'c');
+ QJniObject::callStaticMethod<void>(testClassName,
+ "staticVoidMethodWithArgs",
+ 1,
+ true,
+ 'c');
testClass.callMethod<void>("voidMethod");
testClass.callMethod<void>("voidMethodWithArgs", "(IZC)V", 1, true, 'c');
+ testClass.callMethod<void>("voidMethodWithArgs", 1, true, 'c');
// jboolean -----------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName, "staticBooleanMethod"));
@@ -1056,6 +1106,11 @@ void tst_QJniObject::templateApiCheck()
true,
true,
true));
+ QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName,
+ "staticBooleanMethodWithArgs",
+ true,
+ true,
+ true));
QVERIFY(testClass.callMethod<jboolean>("booleanMethod"));
QVERIFY(testClass.callMethod<jboolean>("booleanMethodWithArgs",
@@ -1063,6 +1118,10 @@ void tst_QJniObject::templateApiCheck()
true,
true,
true));
+ QVERIFY(testClass.callMethod<jboolean>("booleanMethodWithArgs",
+ true,
+ true,
+ true));
// jbyte --------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
@@ -1073,9 +1132,15 @@ void tst_QJniObject::templateApiCheck()
1,
1,
1) == A_BYTE_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
+ "staticByteMethodWithArgs",
+ jbyte(1),
+ jbyte(1),
+ jbyte(1)) == A_BYTE_VALUE);
QVERIFY(testClass.callMethod<jbyte>("byteMethod") == A_BYTE_VALUE);
QVERIFY(testClass.callMethod<jbyte>("byteMethodWithArgs", "(BBB)B", 1, 1, 1) == A_BYTE_VALUE);
+ QVERIFY(testClass.callMethod<jbyte>("byteMethodWithArgs", jbyte(1), jbyte(1), jbyte(1)) == A_BYTE_VALUE);
// jchar --------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
@@ -1086,6 +1151,11 @@ void tst_QJniObject::templateApiCheck()
jchar(1),
jchar(1),
jchar(1)) == A_CHAR_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
+ "staticCharMethodWithArgs",
+ jchar(1),
+ jchar(1),
+ jchar(1)) == A_CHAR_VALUE);
QVERIFY(testClass.callMethod<jchar>("charMethod") == A_CHAR_VALUE);
QVERIFY(testClass.callMethod<jchar>("charMethodWithArgs",
@@ -1093,6 +1163,10 @@ void tst_QJniObject::templateApiCheck()
jchar(1),
jchar(1),
jchar(1)) == A_CHAR_VALUE);
+ QVERIFY(testClass.callMethod<jchar>("charMethodWithArgs",
+ jchar(1),
+ jchar(1),
+ jchar(1)) == A_CHAR_VALUE);
// jshort -------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
@@ -1103,6 +1177,11 @@ void tst_QJniObject::templateApiCheck()
jshort(1),
jshort(1),
jshort(1)) == A_SHORT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
+ "staticShortMethodWithArgs",
+ jshort(1),
+ jshort(1),
+ jshort(1)) == A_SHORT_VALUE);
QVERIFY(testClass.callMethod<jshort>("shortMethod") == A_SHORT_VALUE);
QVERIFY(testClass.callMethod<jshort>("shortMethodWithArgs",
@@ -1110,6 +1189,10 @@ void tst_QJniObject::templateApiCheck()
jshort(1),
jshort(1),
jshort(1)) == A_SHORT_VALUE);
+ QVERIFY(testClass.callMethod<jshort>("shortMethodWithArgs",
+ jshort(1),
+ jshort(1),
+ jshort(1)) == A_SHORT_VALUE);
// jint ---------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
@@ -1120,6 +1203,11 @@ void tst_QJniObject::templateApiCheck()
jint(1),
jint(1),
jint(1)) == A_INT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
+ "staticIntMethodWithArgs",
+ jint(1),
+ jint(1),
+ jint(1)) == A_INT_VALUE);
QVERIFY(testClass.callMethod<jint>("intMethod") == A_INT_VALUE);
QVERIFY(testClass.callMethod<jint>("intMethodWithArgs",
@@ -1127,6 +1215,10 @@ void tst_QJniObject::templateApiCheck()
jint(1),
jint(1),
jint(1)) == A_INT_VALUE);
+ QVERIFY(testClass.callMethod<jint>("intMethodWithArgs",
+ jint(1),
+ jint(1),
+ jint(1)) == A_INT_VALUE);
// jlong --------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
@@ -1137,6 +1229,11 @@ void tst_QJniObject::templateApiCheck()
jlong(1),
jlong(1),
jlong(1)) == A_LONG_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
+ "staticLongMethodWithArgs",
+ jlong(1),
+ jlong(1),
+ jlong(1)) == A_LONG_VALUE);
QVERIFY(testClass.callMethod<jlong>("longMethod") == A_LONG_VALUE);
QVERIFY(testClass.callMethod<jlong>("longMethodWithArgs",
@@ -1144,6 +1241,10 @@ void tst_QJniObject::templateApiCheck()
jlong(1),
jlong(1),
jlong(1)) == A_LONG_VALUE);
+ QVERIFY(testClass.callMethod<jlong>("longMethodWithArgs",
+ jlong(1),
+ jlong(1),
+ jlong(1)) == A_LONG_VALUE);
// jfloat -------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
@@ -1154,6 +1255,11 @@ void tst_QJniObject::templateApiCheck()
jfloat(1.1),
jfloat(1.1),
jfloat(1.1)) == A_FLOAT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
+ "staticFloatMethodWithArgs",
+ jfloat(1.1),
+ jfloat(1.1),
+ jfloat(1.1)) == A_FLOAT_VALUE);
QVERIFY(testClass.callMethod<jfloat>("floatMethod") == A_FLOAT_VALUE);
QVERIFY(testClass.callMethod<jfloat>("floatMethodWithArgs",
@@ -1161,6 +1267,10 @@ void tst_QJniObject::templateApiCheck()
jfloat(1.1),
jfloat(1.1),
jfloat(1.1)) == A_FLOAT_VALUE);
+ QVERIFY(testClass.callMethod<jfloat>("floatMethodWithArgs",
+ jfloat(1.1),
+ jfloat(1.1),
+ jfloat(1.1)) == A_FLOAT_VALUE);
// jdouble ------------------------------------------------------------------------------------
QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
@@ -1171,6 +1281,11 @@ void tst_QJniObject::templateApiCheck()
jdouble(1.1),
jdouble(1.1),
jdouble(1.1)) == A_DOUBLE_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
+ "staticDoubleMethodWithArgs",
+ jdouble(1.1),
+ jdouble(1.1),
+ jdouble(1.1)) == A_DOUBLE_VALUE);
QVERIFY(testClass.callMethod<jdouble>("doubleMethod") == A_DOUBLE_VALUE);
QVERIFY(testClass.callMethod<jdouble>("doubleMethodWithArgs",
@@ -1178,6 +1293,10 @@ void tst_QJniObject::templateApiCheck()
jdouble(1.1),
jdouble(1.1),
jdouble(1.1)) == A_DOUBLE_VALUE);
+ QVERIFY(testClass.callMethod<jdouble>("doubleMethodWithArgs",
+ jdouble(1.1),
+ jdouble(1.1),
+ jdouble(1.1)) == A_DOUBLE_VALUE);
// jobject ------------------------------------------------------------------------------------
{