!have_target: return()

# qt_build_config.prf disables execptions for all Qt modules which don't
# explicitly turn it on again, while the qmake default is to build with
# exceptions. As we want tests to be built like 3rd party applications,
# qt_build_config tells us to re-enable exceptions here.
testcase_exceptions: CONFIG += exceptions

# Set in qt_build_config.prf
testcase_no_bundle: CONFIG -= app_bundle

# cmdline may have been specified and not processed yet
cmdline: CONFIG -= app_bundle

# Allow testcases to mark themselves as not supporting high-DPI
testcase_lowdpi {
    macos {
        !isEmpty(QMAKE_INFO_PLIST): \
            error("QMAKE_INFO_PLIST already set, can't apply testcase_lowdpi")

        QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.disable_highdpi
    } else {
        # TODO: Add support for other platforms if possible
    }
}

benchmark: type = benchmark
else: type = check

$${type}.files =
$${type}.path = .

# Make sure we explicitly load the debug version of the Qt libraries if needed
macos {
    dyld_image_suffix.name = DYLD_IMAGE_SUFFIX
    dyld_image_suffix.value = $$qtPlatformTargetSuffix()
    QT_TOOL_ENV += dyld_image_suffix
}

# Add environment for non-installed builds. Do this first, so the
# 'make' variable expansions don't end up in a batch file/script.
QT_TOOL_NAME = target
qtAddTargetEnv($${type}.commands, QT)

# If the test ends up in a different directory, we should cd to that directory.
TESTRUN_CWD = $$DESTDIR

debug_and_release:debug_and_release_target {
    # But in debug-and-release-target mode we don't want to cd into the debug/release
    # directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do
    # 'cd foo && release/tst_thing.exe', not 'cd foo/release && tst_thing.exe').

    TESTRUN_CWD ~= s/(release|debug)$//
    TEST_TARGET_DIR = $$relative_path($$absolute_path($$DESTDIR, $$OUT_PWD), $$absolute_path($$TESTRUN_CWD, $$OUT_PWD))
}

# Allow for a custom test runner script

android: isEmpty($(TESTRUNNER)) {
    APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
    qtPrepareTool(ANDROIDTESTRUNNER, androidtestrunner)
    qtPrepareTool(ANDROIDDEPLOYQT, androiddeployqt)
    isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json
    contains(QMAKE_HOST.os, Windows): extension = .exe
    $${type}.commands  = $$ANDROIDTESTRUNNER --androiddeployqt \"$$ANDROIDDEPLOYQT --input $$ANDROID_DEPLOYMENT_SETTINGS_FILE\"
    $${type}.commands += --path \"$$OUT_PWD/android-build\"
    $${type}.commands += --adb \"$$shell_path($${ANDROID_SDK_ROOT}$${QMAKE_DIR_SEP}platform-tools$${QMAKE_DIR_SEP}adb$${extension})\"
    $${type}.commands += --make \"$(MAKE) -f $(MAKEFILE)\"
    $${type}.commands += --apk $$APK_PATH
} else: $${type}.commands += $(TESTRUNNER)

unix {
    isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .

    app_bundle: \
        $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
    else: !android: \
        $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
} else {
    # Windows
    !isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $$shell_path($$TEST_TARGET_DIR)$${QMAKE_DIR_SEP}
    $${type}.commands += $${TEST_TARGET_DIR}$(TARGET)
}

# Allow for custom arguments to tests
$${type}.commands += $(TESTARGS)

!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD, ^\\./?): \
    $${type}.commands = $$QMAKE_CD $$shell_path($$TESTRUN_CWD) && $$eval($${type}.commands)

# If the test is marked as insignificant, discard the exit code
insignificant_test: $${type}.commands = -$$eval($${type}.commands)

QMAKE_EXTRA_TARGETS *= $${type}

isEmpty(BUILDS)|build_pass {
    $${type}.depends = first
} else {
    # For exclusive builds, only run the test once.
    $${type}.CONFIG = recursive
    $${type}.target = $${type}_all
    $${type}.recurse_target = $${type}
    $${type}.commands =

    $${type}_first.depends = $$eval($$first(BUILDS).target)-$${type}
    $${type}_first.target = $${type}
    QMAKE_EXTRA_TARGETS += $${type}_first
}

!no_testcase_installs:!contains(INSTALLS, target) {
    # Install tests unless no_testcase_installs is set, or there is already
    # a `target' in INSTALLS.
    #
    # Tests are installed under a directory named after their source folder
    # so that each test has its own directory for testdata etc.
    #
    TEST_FOLDER = $$basename(_PRO_FILE_PWD_)
    target.path = $$[QT_INSTALL_TESTS]/$$TEST_FOLDER
    INSTALLS += target
}

!builtin_testdata:contains(INSTALLS, target) {
    # Install testdata and helpers as well, but only if we're actually installing the test.
    #
    # Testdata is installed relative to the directory containing the testcase
    # binary itself, e.g. this:
    #
    #   CONFIG += testcase
    #   TARGET = tst_qxmlreader
    #
    #   TESTDATA += testdata/test1.xml testdata/test2.xml
    #
    # ... will result in:
    #
    #   /usr/lib/qt5/tests/tst_qxmlreader/tst_qxmlreader
    #   /usr/lib/qt5/tests/tst_qxmlreader/testdata/test1.xml
    #   /usr/lib/qt5/tests/tst_qxmlreader/testdata/test2.xml
    #   ...
    #
    for(file, TESTDATA) {
        tnam = $$file
        tnam ~= s,\\.\\.,dotdot,
        tnam ~= s,[?*],wildcard,
        tnam ~= s,[^A-Za-z0-9],_,
        tdi = testdata_$$tnam

        # TESTDATA consists of the files to install (source)...
        $${tdi}.files = $$file

        # ... and the destination preserves the relative path.
        # Strip any leading ../ from the testdata, so that installation does not escape
        # the test's directory in the case of e.g.
        #
        #  TARGET   = ../tst_qprocess
        #  TESTDATA = ../thing1 ../thing2
        #
        # The testdata should end up at $$[QT_INSTALL_TESTS]/tst_qprocess/thing1,
        # rather than $$[QT_INSTALL_TESTS]/tst_qprocess/../thing1.
        #
        # Note that this does not guarantee the same relative path between test binary
        # and testdata in the build and install tree, but should cover most cases.
        #
        file = $$replace(file, ^(\\.\\./)+, )
        $${tdi}.path = $${target.path}/$$dirname(file)

        INSTALLS += $$tdi
    }

    # Install GENERATED_TESTDATA.
    # Logic is copied from the TESTDATA installation, only difference being that
    # INSTALL target is added with CONFIG = no_check_exist
    for(file, GENERATED_TESTDATA) {
        tnam = $$file
        tnam ~= s,\\.\\.,dotdot,
        tnam ~= s,[?*],wildcard,
        tnam ~= s,[^A-Za-z0-9],_,
        tdi = testdata_$$tnam

        $${tdi}.files = $$file
        $${tdi}.CONFIG = no_check_exist

        file = $$replace(file, ^(\\.\\./)+, )
        $${tdi}.path = $${target.path}/$$dirname(file)

        INSTALLS += $$tdi
    }

    # TEST_HELPER_INSTALLS specifies additional test helper executables for installation.
    #
    # Typical usage is:
    #
    #   TEST_HELPER_INSTALLS += ../some/helper1 ../some/helper2
    #
    # Resulting in the test helpers being installed to:
    #
    #   $$[QT_INSTALL_TESTS]/$$TARGET/some/helper1
    #   $$[QT_INSTALL_TESTS]/$$TARGET/some/helper2
    #
    win32: extension = .exe
    for(test_helper, TEST_HELPER_INSTALLS) {
        test_helper_dir = $$dirname(test_helper)
        output = $$basename(test_helper_dir)
        target = $$basename(test_helper)
        targetName = $$replace(target, ' ', '_') # handle spaces in name
        subTarget = $${targetName}.target
        subInstall = $${targetName}_install
        subConfig = $${subInstall}.CONFIG
        subFiles = $${subInstall}.files
        subPath = $${subInstall}.path
        $$subTarget = $${output}/$${target}$${extension}
        $$subFiles = $${OUT_PWD}/$${test_helper}$${extension}
        $$subPath = $${target.path}/$${output}
        $$subConfig += no_check_exist executable
        INSTALLS += $${subInstall}
    }
}

builtin_testdata {
    # RESOURCES does not support wildcards (for good reasons)
    for (td, TESTDATA): \
        testdata.files += $$files($$absolute_path($$td, $$_PRO_FILE_PWD_))
    # BLACKLIST needs to be added to the testdata
    BLACKLISTPATH = $$_PRO_FILE_PWD_/BLACKLIST
    exists($$BLACKLISTPATH): \
        testdata.files *= $$BLACKLISTPATH
    !isEmpty(testdata.files) {
        testdata.base = $$_PRO_FILE_PWD_
        RESOURCES += testdata
    }

    # Extra compilers don't create wildcards to start with.
    for (td, GENERATED_TESTDATA): \
        gentestdata.files += $$absolute_path($$td, $$OUT_PWD)
    !isEmpty(gentestdata.files) {
        gentestdata.base = $$OUT_PWD
        RESOURCES += gentestdata
    }

    !isEmpty(TEST_HELPER_INSTALLS): \
        error("This platform does not support tests which require helpers.")
}

macx-xcode:bundle:isEmpty(QMAKE_BUNDLE_EXTENSION) {
    QMAKE_PBX_PRODUCT_TYPE = com.apple.product-type.bundle.unit-test
    QMAKE_PBX_BUNDLE_TYPE = wrapper.cfbundle
    QMAKE_BUNDLE_EXTENSION = .xctest
}