1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include <utils/fileutils.h>
29 #include <utils/treemodel.h>
30 
31 #include <QList>
32 #include <QMetaType>
33 #include <QSet>
34 #include <QString>
35 
36 namespace {
37     enum ItemRole {
38         LinkRole = Qt::UserRole + 2, // can be removed if AnnotationRole comes back
39         ItalicRole, // used only inside the delegate
40         TypeRole,
41         EnabledRole,
42         FailedRole  // marker for having failed in last run
43     };
44 }
45 
46 namespace Autotest {
47 
48 class ITestBase;
49 class ITestFramework;
50 class ITestConfiguration;
51 class TestParseResult;
52 enum class TestRunMode;
53 
54 class ITestTreeItem : public Utils::TypedTreeItem<ITestTreeItem>
55 {
56 public:
57 
58     enum Type
59     {
60         Root,
61         GroupNode,
62         TestSuite,
63         TestCase,
64         TestFunction,
65         TestDataTag,
66         TestDataFunction,
67         TestSpecialFunction
68     };
69 
70     enum SortMode {
71         Alphabetically,
72         Naturally
73     };
74 
75     explicit ITestTreeItem(ITestBase *testBase,
76                            const QString &name = QString(),
77                            const Utils::FilePath &filePath = Utils::FilePath(),
78                            Type type = Root);
79 
80     virtual QVariant data(int column, int role) const override;
81     virtual bool setData(int column, const QVariant &data, int role) override;
82     virtual Qt::ItemFlags flags(int column) const override;
83 
84     virtual Qt::CheckState checked() const;
canProvideTestConfiguration()85     virtual bool canProvideTestConfiguration() const { return false; }
testConfiguration()86     virtual ITestConfiguration *testConfiguration() const { return nullptr; }
87     virtual ITestConfiguration *asConfiguration(TestRunMode mode) const;
88 
getAllTestConfigurations()89     virtual QList<ITestConfiguration *> getAllTestConfigurations() const { return {}; }
getSelectedTestConfigurations()90     virtual QList<ITestConfiguration *> getSelectedTestConfigurations() const { return {}; };
getFailedTestConfigurations()91     virtual QList<ITestConfiguration *> getFailedTestConfigurations() const { return {}; }
92 
name()93     const QString name() const { return m_name; }
setName(const QString & name)94     void setName(const QString &name) { m_name = name; }
filePath()95     const Utils::FilePath filePath() const { return m_filePath; }
setFilePath(const Utils::FilePath & filePath)96     void setFilePath(const Utils::FilePath &filePath) { m_filePath = filePath; }
type()97     Type type() const { return m_type; }
line()98     int line() const { return m_line; }
setLine(int line)99     void setLine(int line) { m_line = line;}
testBase()100     ITestBase *testBase() const { return m_testBase; }
101 
102     virtual bool lessThan(const ITestTreeItem *other, SortMode mode) const;
cacheName()103     QString cacheName() const { return m_filePath.toString() + ':' + m_name; }
104 
105 protected:
setType(Type type)106     void setType(Type type) { m_type = type; }
107     Qt::CheckState m_checked = Qt::Checked;
108 
109 private:
110     ITestBase *m_testBase = nullptr; // not owned
111     QString m_name;
112     Utils::FilePath m_filePath;
113     Type m_type;
114     int m_line = 0;
115     bool m_failed = false;
116 };
117 
118 class TestTreeItem : public ITestTreeItem
119 {
120 public:
121     explicit TestTreeItem(ITestFramework *testFramework,
122                           const QString &name = QString(),
123                           const Utils::FilePath &filePath = Utils::FilePath(),
124                           Type type = Root);
125 
126     virtual TestTreeItem *copyWithoutChildren() = 0;
127     virtual QVariant data(int column, int role) const override;
128     bool modifyTestCaseOrSuiteContent(const TestParseResult *result);
129     bool modifyTestFunctionContent(const TestParseResult *result);
130     bool modifyDataTagContent(const TestParseResult *result);
131     bool modifyLineAndColumn(const TestParseResult *result);
132 
133     ITestFramework *framework() const;
setColumn(int column)134     void setColumn(int column) { m_column = column; }
column()135     int column() const { return m_column; }
proFile()136     Utils::FilePath proFile() const { return m_proFile; }
setProFile(const Utils::FilePath & proFile)137     void setProFile(const Utils::FilePath &proFile) { m_proFile = proFile; }
138     void markForRemoval(bool mark);
139     void markForRemovalRecursively(bool mark);
140     virtual void markForRemovalRecursively(const Utils::FilePath &filepath);
removeOnSweepIfEmpty()141     virtual bool removeOnSweepIfEmpty() const { return type() == GroupNode; }
markedForRemoval()142     bool markedForRemoval() const { return m_status == MarkedForRemoval; }
newlyAdded()143     bool newlyAdded() const { return m_status == NewlyAdded; }
144     TestTreeItem *childItem(int at) const;
145     TestTreeItem *parentItem() const;
146 
147     TestTreeItem *findChildByName(const QString &name);
148     TestTreeItem *findChildByFile(const Utils::FilePath &filePath);
149     TestTreeItem *findChildByFileAndType(const Utils::FilePath &filePath, Type type);
150     TestTreeItem *findChildByNameAndFile(const QString &name, const Utils::FilePath &filePath);
151 
debugConfiguration()152     virtual ITestConfiguration *debugConfiguration() const { return nullptr; }
canProvideDebugConfiguration()153     virtual bool canProvideDebugConfiguration() const { return false; }
154     ITestConfiguration *asConfiguration(TestRunMode mode) const final;
155     virtual QList<ITestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const;
156     virtual TestTreeItem *find(const TestParseResult *result) = 0;
157     virtual TestTreeItem *findChild(const TestTreeItem *other) = 0;
158     virtual bool modify(const TestParseResult *result) = 0;
159     virtual bool isGroupNodeFor(const TestTreeItem *other) const;
160     virtual bool isGroupable() const;
161     virtual TestTreeItem *createParentGroupNode() const = 0;
162     // based on (internal) filters this will be used to filter out sub items (and remove them)
163     // returns a copy of the item that contains the filtered out children or nullptr
applyFilters()164     virtual TestTreeItem *applyFilters() { return nullptr; }
165     // decide whether an item should still be added to the treemodel
shouldBeAddedAfterFiltering()166     virtual bool shouldBeAddedAfterFiltering() const { return true; }
167 
168     void forAllChildItems(const std::function<void(TestTreeItem *)> &pred) const;
169     void forFirstLevelChildItems(const std::function<void(TestTreeItem *)> &pred) const;
170     TestTreeItem *findFirstLevelChildItem(const std::function<bool(TestTreeItem *)> &pred) const;
171 protected:
172     void copyBasicDataFrom(const TestTreeItem *other);
173     typedef std::function<bool(const TestTreeItem *)> CompareFunction;
174 
175 private:
176     bool modifyFilePath(const Utils::FilePath &filepath);
177     bool modifyName(const QString &name);
178 
179     enum Status
180     {
181         NewlyAdded,
182         MarkedForRemoval,
183         Cleared
184     };
185 
186     int m_column = 0;
187     Utils::FilePath m_proFile;
188     Status m_status = NewlyAdded;
189 
190     friend class TestTreeModel; // grant access to (protected) findChildBy()
191 };
192 
193 class TestCodeLocationAndType
194 {
195 public:
196     QString m_name;
197     Utils::FilePath m_filePath;
198     int m_line = 0;
199     int m_column = 0;
200     TestTreeItem::Type m_type = TestTreeItem::Root;
201 };
202 
203 typedef QVector<TestCodeLocationAndType> TestCodeLocationList;
204 
205 } // namespace Autotest
206 
207 Q_DECLARE_METATYPE(Autotest::TestTreeItem *)
208 Q_DECLARE_METATYPE(Autotest::TestCodeLocationAndType)
209