aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/autotest/gtest/gtestresult.cpp
blob: 070aa837d38d243ff395893d320ff6681e1149db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#include "gtestresult.h"
#include "gtestconstants.h"
#include "../testframeworkmanager.h"
#include "../testtreeitem.h"

#include <utils/id.h>
#include <utils/qtcassert.h>

#include <QRegularExpression>

using namespace Utils;

namespace Autotest {
namespace Internal {

static ResultHooks::OutputStringHook outputStringHook(const QString &testCaseName)
{
    return [testCaseName](const TestResult &result, bool selected) {
        const QString &desc = result.description();
        QString output;
        switch (result.result()) {
        case ResultType::Pass:
        case ResultType::Fail:
            output = testCaseName;
            if (selected && !desc.isEmpty())
                output.append('\n').append(desc);
            break;
        default:
            output = desc;
            if (!selected)
                output = output.split('\n').first();
        }
        return output;
    };
}

static QString normalizeName(const QString &name)
{
    static const QRegularExpression parameterIndex("/\\d+");

    QString nameWithoutParameterIndices = name;
    nameWithoutParameterIndices.remove(parameterIndex);

    return nameWithoutParameterIndices.split('/').last();
}

static QString normalizeTestName(const QString &testname)
{
    return normalizeName(testname.split(',').first());
}

static bool matchesTestCase(const QString &testCaseName, const TestTreeItem *treeItem)
{
    if (treeItem->type() != TestTreeItem::TestCase)
        return false;

    const QString testItemTestCase = treeItem->parentItem()->name() + '.' + treeItem->name();
    return testItemTestCase == normalizeName(testCaseName);
}

static bool matchesTestSuite(const QString &name, const TestTreeItem *treeItem)
{
    if (treeItem->type() != TestTreeItem::TestSuite)
        return false;

    return treeItem->name() == normalizeTestName(name);
}

static bool matches(const QString &name, const FilePath &projectFile,
                    const QString &testCaseName, const TestTreeItem *treeItem)
{
    if (treeItem->proFile() != projectFile)
        return false;

    if (!testCaseName.isEmpty())
        return matchesTestCase(testCaseName, treeItem);
    return matchesTestSuite(name, treeItem);
}

static ResultHooks::FindTestItemHook findTestItemHook(const FilePath &projectFile,
                                                      const QString &testCaseName)
{
    return [=](const TestResult &result) -> ITestTreeItem * {
        ITestFramework *framework = TestFrameworkManager::frameworkForId(GTest::Constants::FRAMEWORK_ID);
        QTC_ASSERT(framework, return nullptr);
        const TestTreeItem *rootNode = framework->rootNode();
        if (!rootNode)
            return nullptr;

        return rootNode->findAnyChild([&](const TreeItem *item) {
            const auto testTreeItem = static_cast<const TestTreeItem *>(item);
            return testTreeItem && matches(result.name(), projectFile, testCaseName, testTreeItem);
        });
    };
}

struct GTestData
{
    QString m_testCaseName;
    int m_iteration = 1;
};

static ResultHooks::DirectParentHook directParentHook(const QString &testCaseName, int iteration)
{
    return [=](const TestResult &result, const TestResult &other, bool *) -> bool {
        if (!other.extraData().canConvert<GTestData>())
            return false;
        const GTestData otherData = other.extraData().value<GTestData>();

        if (testCaseName == otherData.m_testCaseName) {
            const ResultType thisResult = result.result();
            const ResultType otherResult = other.result();
            if (otherResult == ResultType::MessageInternal || otherResult == ResultType::MessageLocation)
                return thisResult != ResultType::MessageInternal && thisResult != ResultType::MessageLocation;
        }
        if (iteration != otherData.m_iteration)
            return false;
        return testCaseName.isEmpty() && !otherData.m_testCaseName.isEmpty();
    };
}

GTestResult::GTestResult(const QString &id, const QString &name, const FilePath &projectFile,
                         const QString &testCaseName, int iteration)
    : TestResult(id, name, {QVariant::fromValue(GTestData{testCaseName, iteration}),
                            outputStringHook(testCaseName),
                            findTestItemHook(projectFile, testCaseName),
                            directParentHook(testCaseName, iteration)})
{}

} // namespace Internal
} // namespace Autotest

Q_DECLARE_METATYPE(Autotest::Internal::GTestData);