File: testhelper.h

package info (click to toggle)
kdevelop 4%3A25.04.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 73,508 kB
  • sloc: cpp: 291,803; python: 4,322; javascript: 3,518; sh: 1,316; ansic: 703; xml: 414; php: 95; lisp: 66; makefile: 31; sed: 12
file content (140 lines) | stat: -rw-r--r-- 4,863 bytes parent folder | download | duplicates (2)
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
138
139
140
/*
    SPDX-FileCopyrightText: 2009 Niko Sams <niko.sams@gmail.com>
    SPDX-FileCopyrightText: 2016 Aetf <aetf@unlimitedcodeworks.xyz>

    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/

#ifndef KDEVDBG_TESTHELPER_H
#define KDEVDBG_TESTHELPER_H

#include <debugger/interfaces/idebugsession.h>
#include <interfaces/ilaunchconfiguration.h>

#include <KConfigGroup>
#include <KSharedConfig>

#include <QPointer>
#include <QString>
#include <QElapsedTimer>
#include <QUrl>

namespace KDevelop {
class Breakpoint;
class BreakpointModel;
}

class IExecutePlugin;
class QModelIndex;

#define WAIT_FOR_STATE(session, state) \
    do { if (!KDevMI::Testing::waitForState((session), (state), __FILE__, __LINE__)) return; } while (0)

#define WAIT_FOR_STATE_AND_IDLE(session, state) \
    do { if (!KDevMI::Testing::waitForState((session), (state), __FILE__, __LINE__, true)) return; } while (0)

#define WAIT_FOR(session, condition) \
    do { \
        KDevMI::Testing::TestWaiter w((session), #condition, __FILE__, __LINE__); \
        while (w.waitUnless((condition))) /* nothing */ ; \
    } while(0)

#define COMPARE_DATA(index, expected) \
    do { if (!KDevMI::Testing::compareData((index), (expected), __FILE__, __LINE__)) return; } while (0)

#define SKIP_IF_ATTACH_FORBIDDEN() \
    do { \
        if (KDevMI::Testing::isAttachForbidden(__FILE__, __LINE__)) \
            return; \
    } while(0)

namespace KDevMI {

class MIDebugSession;

namespace Testing {

QUrl findExecutable(const QString& name);
QString findSourceFile(const QString& name);
QString findFile(const char* dir, const QString& name);
bool isAttachForbidden(const char* file, int line);

/// @return the path to the test file debugee.cpp
QString debugeeFilePath();
/// @return the URL of the test file debugee.cpp
QUrl debugeeUrl();

KDevelop::BreakpointModel* breakpoints();

/// Add a code breakpoint to debugee.cpp at a given one-based MI line.
KDevelop::Breakpoint* addDebugeeBreakpoint(int miLine);

/// @return one-based MI line of a given breakpoint
int breakpointMiLine(const KDevelop::Breakpoint* breakpoint);
/// @return current one-based MI line in a given session
int currentMiLine(const KDevelop::IDebugSession* session);

bool compareData(const QModelIndex& index, const QString& expected, const char* file, int line, bool useRE = false);

/// Verify that a given thread index's frame stack model has 3 columns, an expected number of threads
/// and returns correct stack frame numbers (at column=0) for the thread index (as the parent index).
/// Check success with RETURN_IF_TEST_FAILED().
void validateColumnCountsThreadCountAndStackFrameNumbers(const QModelIndex& threadIndex, int expectedThreadCount);

bool waitForState(MIDebugSession* session, KDevelop::IDebugSession::DebuggerState state, const char* file, int line,
                  bool waitForIdle = false);

bool waitForAWhile(MIDebugSession* session, int ms, const char* file, int line);

class TestWaiter
{
public:
    TestWaiter(MIDebugSession* session_, const char* condition_, const char* file_, int line_);

    bool waitUnless(bool ok);

private:
    QElapsedTimer stopWatch;
    QPointer<MIDebugSession> session;
    const char* condition;
    const char* file;
    int line;
};

class TestLaunchConfiguration : public KDevelop::ILaunchConfiguration
{
public:
    explicit TestLaunchConfiguration(const QString& executable = QStringLiteral("debuggee_debugee"),
                                     const QUrl& workingDirectory = QUrl{})
        : TestLaunchConfiguration(findExecutable(executable), workingDirectory)
    {}

    explicit TestLaunchConfiguration(const QUrl& executable, const QUrl& workingDirectory);
    const KConfigGroup config() const override { return cfg; }
    KConfigGroup config() override { return cfg; };
    QString name() const override { return QStringLiteral("Test-Launch"); }
    KDevelop::IProject* project() const override { return nullptr; }
    KDevelop::LaunchConfigurationType* type() const override { return nullptr; }

    KConfig* rootConfig() { return c.data(); }
private:
    KConfigGroup cfg;
    KSharedConfigPtr c;
};

void testEnvironmentSet(MIDebugSession* session, const QString& profileName,
                        IExecutePlugin* executePlugin);

void testUnsupportedUrlExpressionBreakpoints(MIDebugSession* session, IExecutePlugin* executePlugin,
                                             bool debuggerSupportsNonAsciiExpressions);

void testBreakpointsOnNoOpLines(MIDebugSession* session, IExecutePlugin* executePlugin,
                                bool debuggerMovesBreakpointFromLicenseNotice);

void testBreakpointErrors(MIDebugSession* session, IExecutePlugin* executePlugin, bool debuggerStopsOnInvalidCondition);

} // namespace Testing

} // end of namespace KDevMI

#endif // KDEVDBG_TESTHELPER_H