Add test coverage for QAxScript and QAxScriptManager

That framework has not aged well, add more tests to avoid regressions,
and to document the complete failure of QAxScriptManager::call to say
what it is expected to do.

Pick-to: 6.5
Change-Id: I20acb3eba3f439d2608ec930d9e90b44a83ef980
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
Volker Hilsheimer 2023-03-18 15:23:46 +01:00
parent e640503b65
commit f6595345f0
4 changed files with 228 additions and 0 deletions

View File

@ -7,4 +7,5 @@ add_subdirectory(dumpcpp)
add_subdirectory(cmake)
if(NOT GCC)
add_subdirectory(qaxscript)
add_subdirectory(qaxscriptmanager)
endif()

View File

@ -13,10 +13,41 @@ class tst_QAxScript : public QObject
Q_OBJECT
private slots:
void call();
void scriptReturnValue();
void scriptOutParameters();
};
void tst_QAxScript::call()
{
QAxScriptManager scriptManager;
const auto scriptCode_js = uR"JS(
function test1() {
return 'JScript';
}
)JS"_s;
const auto scriptCode_vb = uR"VB(
Function test2()
test2 = "VBScript"
End Function
)VB"_s;
QAxScript *jsscript = scriptManager.load(scriptCode_js, u"JS"_s, u"JScript"_s);
QVERIFY2(jsscript, "Unable to load script (CoInitializeEx() called?)");
QVERIFY(jsscript->scriptEngine()->hasIntrospection());
QAxScript *vbscript = scriptManager.load(scriptCode_vb, u"VB"_s, u"VBScript"_s);
QVERIFY2(vbscript, "Unable to load script (CoInitializeEx() called?)");
QVERIFY(vbscript->scriptEngine()->hasIntrospection());
QCOMPARE(jsscript->call("test1()"), "JScript");
QTest::ignoreMessage(QtWarningMsg, "QAxBase::dynamicCallHelper: test1(): No such method in [unknown]");
QTest::ignoreMessage(QtWarningMsg, "\tCandidates are:");
QCOMPARE(vbscript->call("test1()"), QVariant());
QCOMPARE(vbscript->call("test2()"), "VBScript");
QTest::ignoreMessage(QtWarningMsg, "QAxBase::dynamicCallHelper: test2(): No such method in [unknown]");
QTest::ignoreMessage(QtWarningMsg, "\tCandidates are:");
QCOMPARE(jsscript->call("test2()"), QVariant());
}
void tst_QAxScript::scriptReturnValue()
{
QAxScriptManager scriptManager;

View File

@ -0,0 +1,13 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## QAxScriptManager Test:
#####################################################################
qt_internal_add_test(tst_qaxscriptmanager
SOURCES
tst_qaxscriptmanager.cpp
LIBRARIES
Qt::AxContainer
)

View File

@ -0,0 +1,183 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTest>
#include <QAxScriptManager>
#include <QAxScript>
using namespace Qt::StringLiterals;
class tst_QAxScriptManager : public QObject
{
Q_OBJECT
public:
struct Script {
QString language;
QString name;
QString code;
};
private slots:
void functions_data();
void functions();
void scriptNames_data();
void scriptNames();
void script_data();
void script();
void call_data();
void call();
};
void tst_QAxScriptManager::functions_data()
{
const auto scriptCode_js = Script{u"JScript"_s, u"test1"_s, uR"JS(
function js1() {
return 'JScript 1';
}
function js2(value) {
return 'JScript 2';
}
)JS"_s};
const auto scriptCode_vb = Script{u"VBScript"_s, u"test2"_s, uR"VB(
Function vb1()
vb1 = "VBScript 1"
End Function
Function vb2(value)
vb2 = "VBScript 2"
End Function
)VB"_s};
QTest::addColumn<QList<Script>>("scripts");
QTest::addColumn<QStringList>("functions");
QTest::addColumn<QStringList>("signatures");
QTest::addRow("js") << QList{scriptCode_js}
<< QStringList{"js1", "js2"}
<< QStringList{"js1()", "js2(QVariant)"};
QTest::addRow("vb") << QList{scriptCode_vb}
<< QStringList{"vb1", "vb2"}
<< QStringList{"vb1()", "vb2(QVariant)"};
QTest::addRow("both") << QList{scriptCode_js, scriptCode_vb}
<< QStringList{"js1", "js2", "vb1", "vb2"}
<< QStringList{"js1()", "js2(QVariant)", "vb1()", "vb2(QVariant)"};
}
void tst_QAxScriptManager::functions()
{
// QStringList functions(QAxScript::FunctionFlags = QAxScript::FunctionNames) const;
QFETCH(QList<Script>, scripts);
QFETCH(QStringList, functions);
QFETCH(QStringList, signatures);
QAxScriptManager scriptManager;
for (const auto &script : scripts) {
QVERIFY2(scriptManager.load(script.code, script.name, script.language),
"Unable to load script (CoInitializeEx() called?)");
}
functions.sort();
QStringList actualFunctions = scriptManager.functions();
actualFunctions.sort();
QCOMPARE(actualFunctions, functions);
QStringList actualSignatures = scriptManager.functions(QAxScript::FunctionSignatures);
actualSignatures.sort();
QCOMPARE(actualSignatures, signatures);
}
void tst_QAxScriptManager::scriptNames_data()
{
functions_data();
}
void tst_QAxScriptManager::scriptNames()
{
// QStringList scriptNames() const;
QFETCH(QList<Script>, scripts);
QFETCH(QStringList, functions);
QAxScriptManager scriptManager;
QStringList expectedNames;
for (const auto &script : scripts) {
expectedNames << script.name;
QVERIFY2(scriptManager.load(script.code, script.name, script.language),
"Unable to load script (CoInitializeEx() called?)");
}
expectedNames.sort();
QStringList actualNames = scriptManager.scriptNames();
actualNames.sort();
QCOMPARE(actualNames, expectedNames);
}
void tst_QAxScriptManager::script_data()
{
functions_data();
}
void tst_QAxScriptManager::script()
{
QFETCH(QList<Script>, scripts);
QFETCH(QStringList, functions);
QAxScriptManager scriptManager;
QStringList expectedNames;
for (const auto &script : scripts) {
expectedNames << script.name;
QVERIFY2(scriptManager.load(script.code, script.name, script.language),
"Unable to load script (CoInitializeEx() called?)");
}
for (const auto &script : scripts) {
QAxScript *axscript = scriptManager.script(script.name);
QVERIFY(axscript);
QVERIFY(axscript->scriptEngine());
QVERIFY(axscript->scriptEngine()->isValid());
const auto scriptFunctions = axscript->functions();
for (const auto &scriptFunction : scriptFunctions) {
auto index = functions.indexOf(scriptFunction);
QCOMPARE_NE(index, -1);
functions.remove(index);
}
QCOMPARE(axscript->scriptEngine()->scriptLanguage(), script.language);
}
// verify that all functions were found across the different QAxScript objects
QVERIFY(functions.isEmpty());
}
void tst_QAxScriptManager::call_data()
{
functions_data();
}
void tst_QAxScriptManager::call()
{
QFETCH(QList<Script>, scripts);
QFETCH(QStringList, functions);
QFETCH(QStringList, signatures);
QAxScriptManager scriptManager;
for (const auto &script : scripts) {
QAxScript *axScript = scriptManager.load(script.code, script.name, script.language);
QVERIFY2(axScript, "Unable to load script (CoInitializeEx() called?)");
QVERIFY(axScript->scriptEngine());
QVERIFY(axScript->scriptEngine()->hasIntrospection());
}
for (const auto &function : std::as_const(signatures)) {
QVariant result = scriptManager.call(function);
QEXPECT_FAIL("", "QAxScriptManager::call is broken", Continue);
QCOMPARE(result.metaType(), QMetaType::fromType<QString>());
}
}
QTEST_MAIN(tst_QAxScriptManager)
#include "tst_qaxscriptmanager.moc"