diff options
Diffstat (limited to 'tests/auto/tools/qt_cmake_create')
20 files changed, 458 insertions, 0 deletions
diff --git a/tests/auto/tools/qt_cmake_create/CMakeLists.txt b/tests/auto/tools/qt_cmake_create/CMakeLists.txt new file mode 100644 index 0000000000..7d6c49d141 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qt_cmake_create LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + testdata/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qt_cmake_create + SOURCES + tst_qt_cmake_create.cpp + TESTDATA ${test_data} +) diff --git a/tests/auto/tools/qt_cmake_create/testdata/cpp_project/CMakeLists.txt.expected b/tests/auto/tools/qt_cmake_create/testdata/cpp_project/CMakeLists.txt.expected new file mode 100644 index 0000000000..7e646b722d --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/cpp_project/CMakeLists.txt.expected @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.16) +project(cpp_project LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core) +qt_standard_project_setup() + +qt_add_executable(cpp_project + main.cpp +) + +target_link_libraries(cpp_project + PRIVATE + Qt::Core +) diff --git a/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp new file mode 100644 index 0000000000..ae659d5ed4 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/cpp_project/main.cpp @@ -0,0 +1,7 @@ +#include <iostream> + +int main(int, char *[]) +{ + std::cout << "Now I have CMakeLists.txt. Thanks!" << std::endl; + return 0; +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/proto_project/CMakeLists.txt.expected b/tests/auto/tools/qt_cmake_create/testdata/proto_project/CMakeLists.txt.expected new file mode 100644 index 0000000000..1b9ae912b2 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/proto_project/CMakeLists.txt.expected @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.16) +project(proto_project LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Protobuf Grpc) +qt_standard_project_setup() + +qt_add_protobuf(proto_project + GENERATE_PACKAGE_SUBFOLDERS + PROTO_FILES + test.proto +) + +target_link_libraries(proto_project + PRIVATE + Qt::Protobuf + Qt::Grpc +) diff --git a/tests/auto/tools/qt_cmake_create/testdata/proto_project/test.proto b/tests/auto/tools/qt_cmake_create/testdata/proto_project/test.proto new file mode 100644 index 0000000000..e03a5c0832 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/proto_project/test.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +package test; +message Noop { +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/qml_project/CMakeLists.txt.expected b/tests/auto/tools/qt_cmake_create/testdata/qml_project/CMakeLists.txt.expected new file mode 100644 index 0000000000..1187b0e54a --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qml_project/CMakeLists.txt.expected @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.16) +project(qml_project LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Gui Qml Quick Core) +qt_standard_project_setup() + +qt_add_executable(qml_project + main.cpp +) + +qt_add_qml_module(qml_project + URI qml_project + OUTPUT_DIRECTORY qml + VERSION 1.0 + RESOURCE_PREFIX /qt/qml + QML_FILES + TestComponent.qml + main.qml +) + +target_link_libraries(qml_project + PRIVATE + Qt::Gui + Qt::Qml + Qt::Quick + Qt::Core +) diff --git a/tests/auto/tools/qt_cmake_create/testdata/qml_project/TestComponent.qml b/tests/auto/tools/qt_cmake_create/testdata/qml_project/TestComponent.qml new file mode 100644 index 0000000000..f97cbcf115 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qml_project/TestComponent.qml @@ -0,0 +1,4 @@ +import QtQuick + +Item { +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp new file mode 100644 index 0000000000..13c7014d8c --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.cpp @@ -0,0 +1,18 @@ +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(QStringLiteral("qrc:/qt/qml/qml_project/main.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.qml b/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.qml new file mode 100644 index 0000000000..b42c9e7897 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qml_project/main.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Window + +Window { + width: 640 + height: 480 + visible: true + title: "Hello World" + Text { + anchors.centerIn: parent + font.pointSize: 16 + text: "Now I have CMakeLists.txt. Thanks!" + } + TestComponent { + } +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/qrc_project/CMakeLists.txt.expected b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/CMakeLists.txt.expected new file mode 100644 index 0000000000..8a595ac3c2 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/CMakeLists.txt.expected @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.16) +project(qrc_project LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core) +qt_standard_project_setup() + +qt_add_executable(qrc_project + main.cpp +) + +qt_add_resources(qrc_project_resources test.qrc) +target_sources(qrc_project + PRIVATE + ${qrc_project_resources} +) + +target_link_libraries(qrc_project + PRIVATE + Qt::Core +) diff --git a/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp new file mode 100644 index 0000000000..cd8ed8f57b --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/main.cpp @@ -0,0 +1,13 @@ +#include <QFile> +#include <QDebug> + +int main(int, char **) +{ + QFile file(":/test.txt"); + if (!file.open(QFile::ReadOnly)) + return 1; + + QString data = QString::fromUtf8(file.readAll()); + qDebug() << data; + return 0; +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/qrc_project/test.qrc b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/test.qrc new file mode 100644 index 0000000000..adfe37b52e --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/test.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>test.txt</file> + </qresource> +</RCC> diff --git a/tests/auto/tools/qt_cmake_create/testdata/qrc_project/test.txt b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/test.txt new file mode 100644 index 0000000000..6c5b215ebe --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/qrc_project/test.txt @@ -0,0 +1 @@ +Now I have CMakeLists.txt. Thanks! diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_only_project/widget.ui b/tests/auto/tools/qt_cmake_create/testdata/ui_only_project/widget.ui new file mode 100644 index 0000000000..d2c4f620b1 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_only_project/widget.ui @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget</class> + <widget class="QWidget" name="Widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>Widget</string> + </property> + <widget class="QLabel" name="label"> + <property name="geometry"> + <rect> + <x>10</x> + <y>6</y> + <width>781</width> + <height>581</height> + </rect> + </property> + <property name="text"> + <string>Now I have CMakeLists.txt. Thanks!</string> + </property> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/CMakeLists.txt.expected b/tests/auto/tools/qt_cmake_create/testdata/ui_project/CMakeLists.txt.expected new file mode 100644 index 0000000000..6252b71389 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/CMakeLists.txt.expected @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.16) +project(ui_project LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) +qt_standard_project_setup() + +qt_add_executable(ui_project + main.cpp + widget.cpp + widget.h +) + +target_sources(ui_project + PRIVATE + widget.ui +) + +target_link_libraries(ui_project + PRIVATE + Qt::Core + Qt::Gui + Qt::Widgets +) diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp b/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp new file mode 100644 index 0000000000..b0a4ec2647 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/main.cpp @@ -0,0 +1,11 @@ +#include "widget.h" + +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + return a.exec(); +} diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp new file mode 100644 index 0000000000..815d5f8c4b --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.cpp @@ -0,0 +1,15 @@ +#include "widget.h" +#include "ui_widget.h" + +Widget::Widget(QWidget *parent) + : QWidget(parent) + , ui(new Ui::Widget) +{ + ui->setupUi(this); +} + +Widget::~Widget() +{ + delete ui; +} + diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h new file mode 100644 index 0000000000..1fe2322b13 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.h @@ -0,0 +1,21 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +namespace Ui { class Widget; } +QT_END_NAMESPACE + +class Widget : public QWidget +{ + Q_OBJECT + +public: + Widget(QWidget *parent = nullptr); + ~Widget(); + +private: + Ui::Widget *ui; +}; +#endif // WIDGET_H diff --git a/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.ui b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.ui new file mode 100644 index 0000000000..d2c4f620b1 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/testdata/ui_project/widget.ui @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Widget</class> + <widget class="QWidget" name="Widget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>Widget</string> + </property> + <widget class="QLabel" name="label"> + <property name="geometry"> + <rect> + <x>10</x> + <y>6</y> + <width>781</width> + <height>581</height> + </rect> + </property> + <property name="text"> + <string>Now I have CMakeLists.txt. Thanks!</string> + </property> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/tools/qt_cmake_create/tst_qt_cmake_create.cpp b/tests/auto/tools/qt_cmake_create/tst_qt_cmake_create.cpp new file mode 100644 index 0000000000..6bbc58ef32 --- /dev/null +++ b/tests/auto/tools/qt_cmake_create/tst_qt_cmake_create.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> +#include <QtTest> + +#include <QLibraryInfo> +#include <QLatin1StringView> +#include <QDir> +#include <QFileInfo> +#include <QProcess> +#include <QCryptographicHash> + +#include <array> + +using namespace Qt::Literals::StringLiterals; + +class tst_qt_cmake_create : public QObject +{ + Q_OBJECT + +public: + tst_qt_cmake_create(); + +private slots: + void init(); + void initTestCase(); + void generatingCMakeLists_data(); + void generatingCMakeLists(); + +private: + QString m_testWorkDir; + QString m_shell; + QString m_cmd; +}; + +tst_qt_cmake_create::tst_qt_cmake_create() : m_testWorkDir(qApp->applicationDirPath()) { } + +void tst_qt_cmake_create::initTestCase() +{ + QString binpath = QLibraryInfo::path(QLibraryInfo::BinariesPath); +#ifdef Q_OS_WINDOWS + m_shell = QString("cmd.exe"); + m_cmd = QString("%1/qt-cmake-create.bat").arg(binpath); +#else + m_shell = QString("/bin/sh"); + m_cmd = QString("%1/qt-cmake-create").arg(binpath); + QVERIFY(QFile::exists(m_shell)); +#endif + + QVERIFY(QFile::exists(m_cmd)); +} + +void tst_qt_cmake_create::init() +{ + QFETCH(QString, projectDirPath); + QDir workDir(m_testWorkDir); + QString fullProjectPath = m_testWorkDir + '/' + projectDirPath; + if (workDir.exists(fullProjectPath)) { + QDir projectDir(projectDirPath); + projectDir.removeRecursively(); + } + workDir.mkdir(projectDirPath); + auto testDataPath = QFINDTESTDATA("testdata"_L1 + '/' + projectDirPath); + QVERIFY(QFile::exists(testDataPath)); + + for (const auto &fileInfo : QDir(testDataPath).entryInfoList(QDir::Files)) { + QVERIFY(QFile::copy(fileInfo.absoluteFilePath(), + fullProjectPath + '/' + fileInfo.fileName())); + } +} + +void tst_qt_cmake_create::generatingCMakeLists_data() +{ + QTest::addColumn<QString>("projectDirPath"); + QTest::addColumn<bool>("expectPass"); + QTest::addColumn<QString>("workDir"); + + const std::array<QLatin1StringView, 5> expectPass = { + "cpp"_L1, "proto"_L1, "qml"_L1, "qrc"_L1, "ui"_L1, + }; + + const std::array<QString, 5> workDirs = { + m_testWorkDir, ""_L1, m_testWorkDir, ""_L1, m_testWorkDir, + }; + + static_assert(expectPass.size() == workDirs.size()); + + const QLatin1StringView expectFail[] = { + "ui_only"_L1, + }; + + for (size_t i = 0; i < expectPass.size(); ++i) { + const auto type = expectPass.at(i); + QTest::addRow("tst_qt_cmake_create_%s", type.data()) + << QString("%1_project").arg(type) << true << workDirs.at(i); + } + + for (const auto type : expectFail) { + QTest::addRow("tst_qt_cmake_create_%s", type.data()) + << QString("%1_project").arg(type) << false << QString(); + } +} + +void tst_qt_cmake_create::generatingCMakeLists() +{ + QFETCH(QString, projectDirPath); + QFETCH(bool, expectPass); + QFETCH(QString, workDir); + + QString fullProjectPath = m_testWorkDir + '/' + projectDirPath; + QProcess command; + QStringList arguments = { +#ifdef Q_OS_WINDOWS + "/C"_L1, +#endif + m_cmd + }; + + QString workingDirectory = fullProjectPath; + if (!workDir.isEmpty()) { + workingDirectory = workDir; + arguments.append(fullProjectPath); + } + command.setProgram(m_shell); + command.setArguments(arguments); + command.setWorkingDirectory(workingDirectory); + + command.start(); + QVERIFY(command.waitForFinished()); + QCOMPARE(command.exitCode() == 0, expectPass); + + QFile actualFile = QFile(fullProjectPath + '/' + "CMakeLists.txt"_L1); + + // Skip the rest if we expect that qt-cmake-create should exit with error + if (!expectPass) { + QVERIFY(!actualFile.exists()); + return; + } + + QFile expectedFile = QFile(fullProjectPath + '/' + "CMakeLists.txt.expected"_L1); + QVERIFY(actualFile.open(QFile::ReadOnly)); + QVERIFY(expectedFile.open(QFile::ReadOnly)); + + auto actualData = actualFile.readAll(); + actualData.replace(QByteArrayView("\r\n"), QByteArrayView("\n")); + auto expectedData = expectedFile.readAll(); + expectedData.replace(QByteArrayView("\r\n"), QByteArrayView("\n")); + + static auto hash = [](const QByteArray &data) { + return QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex(); + }; + QCOMPARE_EQ(hash(actualData), hash(expectedData)); +} + +QTEST_MAIN(tst_qt_cmake_create) +#include "tst_qt_cmake_create.moc" |