Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++
++ #include <QtCore/qdir.h>
++ #include <QtCore/qdebug.h>
++ #include <QtCore/qfile.h>
++ #include <QtCore/qbytearray.h>
++ #include <QtCore/qjsondocument.h>
++ #include <QtCore/qlibraryinfo.h>
++ #include <QtCore/qprocess.h>
++
++ #include <QtTest/qtest.h>
++
++ using namespace Qt::StringLiterals;
++
++ class tst_qtattributionsscanner : public QObject
++ {
++ Q_OBJECT
++ public:
++ tst_qtattributionsscanner();
++
++ private slots:
++ void test_data();
++ void test();
++
++ private:
++ void readExpectedFile(const QString &baseDir, const QString &fileName, QByteArray *content);
++
++ QString m_cmd;
++ QString m_basePath;
++ };
++
++
++ tst_qtattributionsscanner::tst_qtattributionsscanner()
++ {
++ QString binPath = QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath);
++ m_cmd = binPath + QLatin1String("/qtattributionsscanner");
++ m_basePath = QFINDTESTDATA("testdata");
++ }
++
++
++ void tst_qtattributionsscanner::test_data()
++ {
++ QTest::addColumn<QString>("input");
++ QTest::addColumn<bool>("success");
++ QTest::addColumn<QString>("stdout_file");
++ QTest::addColumn<QString>("stderr_file");
++
++ QTest::newRow("good") << QStringLiteral("good") << true << QStringLiteral("good/expected.json")
++ << QStringLiteral("good/expected.error");
++ QTest::newRow("warnings (incomplete)") << QStringLiteral("warnings/incomplete") << false
++ << QStringLiteral("warnings/incomplete/expected.json")
++ << QStringLiteral("warnings/incomplete/expected.error");
++ QTest::newRow("warnings (unknown attribute)")
++ << QStringLiteral("warnings/unknown") << false
++ << QStringLiteral("warnings/unknown/expected.json")
++ << QStringLiteral("warnings/unknown/expected.error");
++ QTest::newRow("singlefile") << QStringLiteral("good/minimal/qt_attribution_test.json") << true
++ << QStringLiteral("good/minimal/expected.json")
++ << QStringLiteral("good/minimal/expected.error");
++ QTest::newRow("variants") << QStringLiteral("good/variants/qt_attribution_test.json") << true
++ << QStringLiteral("good/variants/expected.json")
++ << QStringLiteral("good/variants/expected.error");
++ QTest::newRow("local_license") << QStringLiteral("good/local_license/qt_attribution_test.json") << true
++ << QStringLiteral("good/local_license/expected.json")
++ << QStringLiteral("good/local_license/expected.error");
++ }
++
++ void tst_qtattributionsscanner::readExpectedFile(const QString &baseDir, const QString &fileName, QByteArray *content)
++ {
++ QFile file(QDir(m_basePath).absoluteFilePath(fileName));
++ QVERIFY2(file.open(QIODevice::ReadOnly | QIODevice::Text),
++ ("Could not open "_ba + file.fileName().toLocal8Bit()).constData());
++ *content = file.readAll();
++ content->replace("%{PWD}", baseDir.toUtf8());
++
++ QDir licensesDir(QStringLiteral(QTTOOLS_LICENSES_DIR));
++ content->replace("%{LICENSES_DIR}", licensesDir.canonicalPath().toUtf8());
++ }
++
++ void tst_qtattributionsscanner::test()
++ {
++ QFETCH(QString, input);
++ QFETCH(bool, success);
++ QFETCH(QString, stdout_file);
++ QFETCH(QString, stderr_file);
++
++ QString dir = QDir(m_basePath).absoluteFilePath(input);
++ if (QFileInfo(dir).isFile())
++ dir = QFileInfo(dir).absolutePath();
++
++ QProcess proc;
++ const QStringList arguments{dir, "--output-format", "json"};
++ QString command = m_cmd + ' ' + arguments.join(' ');
++ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
++ env.insert("QT_ATTRIBUTIONSSCANNER_TEST", "1");
++ proc.setProcessEnvironment(env);
++ proc.start(m_cmd, arguments, QIODevice::ReadWrite | QIODevice::Text);
++
++ QVERIFY2(proc.waitForStarted(), qPrintable(command + QLatin1String(" :") + proc.errorString()));
++ QVERIFY2(proc.waitForFinished(30000), qPrintable(command));
++
++ QVERIFY2(proc.exitStatus() == QProcess::NormalExit,
++ ("\"qtattributionsscanner "_ba + m_cmd.toLatin1() + "\" crashed"_ba).constData());
++ QVERIFY2(success ? (proc.exitCode() == 0) : (proc.exitCode() != 0),
++ ("\"qtattributionsscanner "_ba + m_cmd.toLatin1() + "\" exited with code "_ba
++ + QByteArray::number(proc.exitCode())).constData());
++
++ { // compare error output
++ QByteArray stdErr = proc.readAllStandardError();
++ stdErr.replace(QDir::separator().toLatin1(), "/");
++
++ QByteArray expectedErrorOutput;
++ readExpectedFile(dir, stderr_file, &expectedErrorOutput);
++
++ QCOMPARE(stdErr, expectedErrorOutput);
++ }
++
++ if (proc.exitCode() == 0) {
++ // compare json output
++ QByteArray stdOut = proc.readAllStandardOutput();
++
++ QJsonParseError jsonError;
++ QJsonDocument actualJson = QJsonDocument::fromJson(stdOut, &jsonError);
++ QVERIFY2(!actualJson.isNull(),
++ ("Invalid output: "_ba + jsonError.errorString().toLatin1()).constData());
++
++ QByteArray expectedOutput;
++ readExpectedFile(dir, stdout_file, &expectedOutput);
++ QJsonDocument expectedJson = QJsonDocument::fromJson(expectedOutput);
++
++ if (!QTest::qCompare(actualJson, expectedJson, "actualJson", "expectedJson", __FILE__, __LINE__)) {
++ qWarning() << "Actual (actualJson) :" << actualJson;
++ qWarning() << "Expected (expectedJson):" << expectedJson;
++ return;
++ }
++ }
++ }
++
++ QTEST_MAIN(tst_qtattributionsscanner)
++ #include "tst_qtattributionsscanner.moc"