Changeset View
Changeset View
Standalone View
Standalone View
debuggers/lldb/unittests/test_lldbformatters.cpp
Show All 34 Lines | |||||
35 | #include <tests/autotestshell.h> | 35 | #include <tests/autotestshell.h> | ||
36 | #include <tests/testcore.h> | 36 | #include <tests/testcore.h> | ||
37 | 37 | | |||
38 | #include <KConfig> | 38 | #include <KConfig> | ||
39 | #include <KConfigGroup> | 39 | #include <KConfigGroup> | ||
40 | #include <KSharedConfig> | 40 | #include <KSharedConfig> | ||
41 | 41 | | |||
42 | #include <QDebug> | 42 | #include <QDebug> | ||
43 | #include <QRegularExpression> | ||||
43 | #include <QString> | 44 | #include <QString> | ||
44 | #include <QTest> | 45 | #include <QTest> | ||
45 | #include <QUrl> | 46 | #include <QUrl> | ||
46 | 47 | | |||
48 | #include <algorithm> | ||||
49 | #include <vector> | ||||
50 | | ||||
47 | #define WAIT_FOR_STATE(session, state) \ | 51 | #define WAIT_FOR_STATE(session, state) \ | ||
48 | do { if (!KDevMI::LLDB::waitForState((session), (state), __FILE__, __LINE__)) return; } while (0) | 52 | do { if (!KDevMI::LLDB::waitForState((session), (state), __FILE__, __LINE__)) return; } while (0) | ||
49 | 53 | | |||
50 | #define WAIT_FOR_STATE_AND_IDLE(session, state) \ | 54 | #define WAIT_FOR_STATE_AND_IDLE(session, state) \ | ||
51 | do { if (!KDevMI::LLDB::waitForState((session), (state), __FILE__, __LINE__, true)) return; } while (0) | 55 | do { if (!KDevMI::LLDB::waitForState((session), (state), __FILE__, __LINE__, true)) return; } while (0) | ||
52 | 56 | | |||
53 | #define WAIT_FOR_A_WHILE(session, ms) \ | 57 | #define WAIT_FOR_A_WHILE_AND_IDLE(session, ms) \ | ||
54 | do { if (!KDevMI::LLDB::waitForAWhile((session), (ms), __FILE__, __LINE__)) return; } while (0) | 58 | do { if (!KDevMI::LLDB::waitForAWhile((session), (ms), __FILE__, __LINE__)) return; \ | ||
59 | if (!KDevMI::LLDB::waitForState((session), DebugSession::PausedState, __FILE__, __LINE__, true)) \ | ||||
60 | return; \ | ||||
61 | } while (0) | ||||
55 | 62 | | |||
56 | #define WAIT_FOR(session, condition) \ | 63 | #define WAIT_FOR(session, condition) \ | ||
57 | do { \ | 64 | do { \ | ||
58 | KDevMI::LLDB::TestWaiter w((session), #condition, __FILE__, __LINE__); \ | 65 | KDevMI::LLDB::TestWaiter w((session), #condition, __FILE__, __LINE__); \ | ||
59 | while (w.waitUnless((condition))) /* nothing */ ; \ | 66 | while (w.waitUnless((condition))) /* nothing */ ; \ | ||
60 | } while(0) | 67 | } while(0) | ||
61 | 68 | | |||
62 | #define COMPARE_DATA(index, expected) \ | 69 | #define COMPARE_DATA(index, expected) \ | ||
63 | do { if (!KDevMI::LLDB::compareData((index), (expected), __FILE__, __LINE__)) return; } while (0) | 70 | do { if (!KDevMI::LLDB::compareData((index), (expected), __FILE__, __LINE__)) return; } while (0) | ||
64 | 71 | | |||
65 | #define VERIFY_QSTRING(row, name, expected) \ | 72 | #define VERIFY_LOCAL(row, name, summary, children) \ | ||
66 | do { if (!verifyQString((row), (name), (expected), __FILE__, __LINE__)) return; } while (0) | 73 | do { \ | ||
74 | if (!verifyVariable((row), (name), (summary), (children), __FILE__, __LINE__)) \ | ||||
75 | return; \ | ||||
76 | } while (0) | ||||
77 | | ||||
78 | #define VERIFY_WATCH(row, name, summary, children) \ | ||||
79 | do { \ | ||||
80 | if (!verifyVariable((row), (name), (summary), (children), __FILE__, __LINE__, false)) \ | ||||
81 | return; \ | ||||
82 | } while (0) | ||||
67 | 83 | | |||
68 | #define findSourceFile(name) \ | 84 | #define findSourceFile(name) \ | ||
69 | findSourceFile(__FILE__, (name)) | 85 | findSourceFile(__FILE__, (name)) | ||
70 | 86 | | |||
71 | using namespace KDevelop; | 87 | using namespace KDevelop; | ||
72 | using namespace KDevMI::LLDB; | 88 | using namespace KDevMI::LLDB; | ||
73 | 89 | | |||
74 | class TestLaunchConfiguration : public ILaunchConfiguration | 90 | class TestLaunchConfiguration : public ILaunchConfiguration | ||
75 | { | 91 | { | ||
76 | public: | 92 | public: | ||
77 | TestLaunchConfiguration(const QString& executable, | 93 | explicit TestLaunchConfiguration(const QString& executable, | ||
78 | const QUrl& workingDirectory = QUrl()) { | 94 | const QUrl& workingDirectory = QUrl()) { | ||
79 | auto execPath = findExecutable(executable); | 95 | auto execPath = findExecutable(executable); | ||
80 | qDebug() << "FIND" << execPath; | 96 | qDebug() << "FIND" << execPath; | ||
81 | c = new KConfig(); | 97 | c = new KConfig(); | ||
82 | c->deleteGroup("launch"); | 98 | c->deleteGroup("launch"); | ||
83 | cfg = c->group("launch"); | 99 | cfg = c->group("launch"); | ||
84 | cfg.writeEntry("isExecutable", true); | 100 | cfg.writeEntry("isExecutable", true); | ||
85 | cfg.writeEntry("Executable", execPath); | 101 | cfg.writeEntry("Executable", execPath); | ||
Show All 29 Lines | 122 | public: | |||
115 | } | 131 | } | ||
116 | }; | 132 | }; | ||
117 | 133 | | |||
118 | VariableCollection *LldbFormattersTest::variableCollection() | 134 | VariableCollection *LldbFormattersTest::variableCollection() | ||
119 | { | 135 | { | ||
120 | return m_core->debugController()->variableCollection(); | 136 | return m_core->debugController()->variableCollection(); | ||
121 | } | 137 | } | ||
122 | 138 | | |||
123 | LldbVariable *LldbFormattersTest::watchVariableAt(int i) | 139 | QModelIndex LldbFormattersTest::watchVariableIndexAt(int i, int col) | ||
124 | { | 140 | { | ||
125 | auto watchRoot = variableCollection()->indexForItem(variableCollection()->watches(), 0); | 141 | auto watchRoot = variableCollection()->indexForItem(variableCollection()->watches(), 0); | ||
126 | auto idx = variableCollection()->index(i, 0, watchRoot); | 142 | return variableCollection()->index(i, col, watchRoot); | ||
127 | return dynamic_cast<LldbVariable*>(variableCollection()->itemForIndex(idx)); | | |||
128 | } | 143 | } | ||
129 | 144 | | |||
130 | QModelIndex LldbFormattersTest::localVariableIndexAt(int i, int col) | 145 | QModelIndex LldbFormattersTest::localVariableIndexAt(int i, int col) | ||
131 | { | 146 | { | ||
132 | auto localRoot = variableCollection()->indexForItem(variableCollection()->locals(), 0); | 147 | auto localRoot = variableCollection()->indexForItem(variableCollection()->locals(), 0); | ||
133 | return variableCollection()->index(i, col, localRoot); | 148 | return variableCollection()->index(i, col, localRoot); | ||
134 | } | 149 | } | ||
135 | 150 | | |||
151 | // Note: line is zero-based | ||||
136 | KDevelop::Breakpoint* LldbFormattersTest::addCodeBreakpoint(const QUrl& location, int line) | 152 | KDevelop::Breakpoint* LldbFormattersTest::addCodeBreakpoint(const QUrl& location, int line) | ||
137 | { | 153 | { | ||
138 | return m_core->debugController()->breakpointModel()->addCodeBreakpoint(location, line); | 154 | return m_core->debugController()->breakpointModel()->addCodeBreakpoint(location, line); | ||
139 | } | 155 | } | ||
140 | 156 | | |||
141 | // Called before the first testfunction is executed | 157 | // Called before the first testfunction is executed | ||
142 | void LldbFormattersTest::initTestCase() | 158 | void LldbFormattersTest::initTestCase() | ||
143 | { | 159 | { | ||
Show All 19 Lines | 177 | { | |||
163 | KConfigGroup bpCfg = KSharedConfig::openConfig()->group("breakpoints"); | 179 | KConfigGroup bpCfg = KSharedConfig::openConfig()->group("breakpoints"); | ||
164 | bpCfg.writeEntry("number", 0); | 180 | bpCfg.writeEntry("number", 0); | ||
165 | bpCfg.sync(); | 181 | bpCfg.sync(); | ||
166 | 182 | | |||
167 | auto count = m_core->debugController()->breakpointModel()->rowCount(); | 183 | auto count = m_core->debugController()->breakpointModel()->rowCount(); | ||
168 | m_core->debugController()->breakpointModel()->removeRows(0, count); | 184 | m_core->debugController()->breakpointModel()->removeRows(0, count); | ||
169 | 185 | | |||
170 | while (variableCollection()->watches()->childCount() > 0) { | 186 | while (variableCollection()->watches()->childCount() > 0) { | ||
171 | auto var = watchVariableAt(0); | 187 | auto idx = watchVariableIndexAt(0); | ||
188 | auto var = dynamic_cast<LldbVariable*>(variableCollection()->itemForIndex(idx)); | ||||
172 | if (!var) break; | 189 | if (!var) break; | ||
173 | var->die(); | 190 | var->die(); | ||
174 | } | 191 | } | ||
175 | 192 | | |||
176 | m_session = new TestDebugSession; | 193 | m_session = new TestDebugSession; | ||
177 | } | 194 | } | ||
178 | 195 | | |||
179 | void LldbFormattersTest::cleanup() | 196 | void LldbFormattersTest::cleanup() | ||
180 | { | 197 | { | ||
181 | // Called after every testfunction | 198 | // Called after every testfunction | ||
182 | if (m_session) | 199 | if (m_session) | ||
183 | m_session->stopDebugger(); | 200 | m_session->stopDebugger(); | ||
184 | WAIT_FOR_STATE(m_session, DebugSession::EndedState); | 201 | WAIT_FOR_STATE(m_session, DebugSession::EndedState); | ||
185 | m_session.clear(); | 202 | m_session.clear(); | ||
186 | } | 203 | } | ||
187 | 204 | | |||
188 | bool LldbFormattersTest::verifyQString(int index, const QString &name, | 205 | bool LldbFormattersTest::verifyVariable(int index, const QString &name, | ||
189 | const QString &expected, | 206 | const QString &expectedSummary, | ||
190 | const char *file, int line) | 207 | QStringList expectedChildren, | ||
191 | { | 208 | const char *file, int line, | ||
192 | auto varidx = localVariableIndexAt(index, 0); | 209 | bool isLocal, bool useRE, bool unordered) | ||
193 | auto var = variableCollection()->itemForIndex(varidx); | 210 | { | ||
211 | QList<QPair<QString, QString>> childrenPairs; | ||||
212 | childrenPairs.reserve(expectedChildren.size()); | ||||
213 | if (unordered) { | ||||
214 | qDebug() << "useRE set to true when unordered = true"; | ||||
215 | useRE = true; | ||||
216 | expectedChildren.sort(); | ||||
217 | for (auto c : expectedChildren) { | ||||
218 | childrenPairs << qMakePair(QStringLiteral(R"(^\[\d+\]$)"), c); | ||||
219 | } | ||||
220 | } else { | ||||
221 | for (int i = 0; i != expectedChildren.size(); ++i) { | ||||
222 | childrenPairs << qMakePair(QStringLiteral("[%0]").arg(i), expectedChildren[i]); | ||||
223 | } | ||||
224 | } | ||||
225 | return verifyVariable(index, name, expectedSummary, childrenPairs, file, line, isLocal, useRE, unordered); | ||||
226 | } | ||||
227 | | ||||
228 | bool LldbFormattersTest::verifyVariable(int index, const QString &name, | ||||
229 | const QString &expectedSummary, | ||||
230 | QList<QPair<QString, QString>> expectedChildren, | ||||
231 | const char *file, int line, | ||||
232 | bool isLocal, bool useRE, bool unordered) | ||||
233 | { | ||||
234 | QModelIndex varIdx, summaryIdx; | ||||
235 | if (isLocal) { | ||||
236 | varIdx = localVariableIndexAt(index, 0); | ||||
237 | summaryIdx = localVariableIndexAt(index, 1); | ||||
238 | } else { | ||||
239 | varIdx = watchVariableIndexAt(index, 0); | ||||
240 | summaryIdx = watchVariableIndexAt(index, 1); | ||||
241 | } | ||||
194 | 242 | | |||
195 | if (!compareData(varidx, name, file, line)) { | 243 | if (!compareData(varIdx, name, file, line)) { | ||
196 | return false; | 244 | return false; | ||
197 | } | 245 | } | ||
198 | if (!compareData(localVariableIndexAt(index, 1), Utils::quote(expected), file, line)) { | 246 | if (!compareData(summaryIdx, expectedSummary, file, line, useRE)) { | ||
199 | return false; | 247 | return false; | ||
200 | } | 248 | } | ||
201 | 249 | | |||
202 | // fetch all children | 250 | // fetch all children | ||
251 | auto var = variableCollection()->itemForIndex(varIdx); | ||||
203 | auto childCount = 0; | 252 | auto childCount = 0; | ||
204 | while (childCount != variableCollection()->rowCount(varidx)) { | 253 | while (childCount != variableCollection()->rowCount(varIdx)) { | ||
205 | childCount = variableCollection()->rowCount(varidx); | 254 | childCount = variableCollection()->rowCount(varIdx); | ||
206 | var->fetchMoreChildren(); | 255 | var->fetchMoreChildren(); | ||
207 | if (!waitForAWhile(m_session, 50, file, line)) | 256 | if (!waitForAWhile(m_session, 50, file, line)) | ||
208 | return false; | 257 | return false; | ||
209 | } | 258 | } | ||
210 | if (childCount != expected.length()) { | 259 | if (childCount != expectedChildren.length()) { | ||
211 | QTest::qFail(qPrintable(QString("'%0' didn't match expected '%1' in %2:%3") | 260 | QTest::qFail(qPrintable(QString("'%0' didn't match expected '%1' in %2:%3") | ||
212 | .arg(childCount).arg(expected.length()).arg(file).arg(line)), | 261 | .arg(childCount).arg(expectedChildren.length()).arg(file).arg(line)), | ||
213 | file, line); | 262 | file, line); | ||
214 | return false; | 263 | return false; | ||
215 | } | 264 | } | ||
216 | 265 | | |||
266 | QVector<int> theOrder; | ||||
267 | theOrder.reserve(childCount); | ||||
268 | for (int i = 0; i != childCount; ++i) { | ||||
269 | theOrder.push_back(i); | ||||
270 | } | ||||
271 | if (unordered) { | ||||
272 | qDebug() << "actual list sorted for unordered compare"; | ||||
273 | std::sort(theOrder.begin(), theOrder.end(), [&](int a, int b){ | ||||
274 | auto indexA = variableCollection()->index(a, 1, varIdx); | ||||
275 | auto indexB = variableCollection()->index(b, 1, varIdx); | ||||
276 | return indexA.model()->data(indexA, Qt::DisplayRole).toString() | ||||
277 | < indexB.model()->data(indexB, Qt::DisplayRole).toString(); | ||||
278 | }); | ||||
279 | std::sort(expectedChildren.begin(), expectedChildren.end(), | ||||
280 | [](const QPair<QString, QString> &a, const QPair<QString, QString> &b){ | ||||
281 | return a.second < b.second; | ||||
282 | }); | ||||
283 | qDebug() << "sorted actual order" << theOrder; | ||||
284 | qDebug() << "sorted expectedChildren" << expectedChildren; | ||||
285 | } | ||||
286 | | ||||
217 | for (int i = 0; i != childCount; ++i) { | 287 | for (int i = 0; i != childCount; ++i) { | ||
218 | if (!compareData(variableCollection()->index(i, 0, varidx), | 288 | if (!compareData(variableCollection()->index(theOrder[i], 0, varIdx), | ||
219 | QString("[%0]").arg(i), file, line)) { | 289 | expectedChildren[i].first, file, line, useRE)) { | ||
220 | return false; | 290 | return false; | ||
221 | } | 291 | } | ||
222 | if (!compareData(variableCollection()->index(i, 1, varidx), | 292 | | ||
223 | QString("'%0'").arg(expected[i]), file, line)) { | 293 | if (!compareData(variableCollection()->index(theOrder[i], 1, varIdx), | ||
294 | expectedChildren[i].second, file, line, useRE)) { | ||||
224 | return false; | 295 | return false; | ||
225 | } | 296 | } | ||
226 | } | 297 | } | ||
227 | return true; | 298 | return true; | ||
228 | } | 299 | } | ||
229 | 300 | | |||
301 | void LldbFormattersTest::testQChar() | ||||
302 | { | ||||
303 | TestLaunchConfiguration cfg("lldb_qchar"); | ||||
304 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qchar.cpp")), 4); | ||||
305 | | ||||
306 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||||
307 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
308 | | ||||
309 | // Should be two rows ('auto', 'local') | ||||
310 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
311 | | ||||
312 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
313 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
314 | | ||||
315 | QList<QPair<QString, QString>> children; | ||||
316 | children << qMakePair(QStringLiteral("ucs"), QStringLiteral("107")); | ||||
317 | | ||||
318 | VERIFY_LOCAL(0, "c", "'k'", children); | ||||
319 | } | ||||
320 | | ||||
230 | void LldbFormattersTest::testQString() | 321 | void LldbFormattersTest::testQString() | ||
231 | { | 322 | { | ||
232 | TestLaunchConfiguration cfg("lldb_qstring"); | 323 | TestLaunchConfiguration cfg("lldb_qstring"); | ||
233 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qstring.cpp")), 4); | 324 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qstring.cpp")), 4); | ||
234 | 325 | | |||
235 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | 326 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
236 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | 327 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
237 | 328 | | |||
329 | // Should be two rows ('auto', 'local') | ||||
238 | QCOMPARE(variableCollection()->rowCount(), 2); | 330 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
239 | 331 | | |||
240 | VERIFY_QSTRING(0, "s", "test string"); | 332 | variableCollection()->expanded(localVariableIndexAt(0)); | ||
333 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
334 | | ||||
335 | QString expected = QString::fromUtf8("test最后一个不是特殊字符'\"\\u6211"); | ||||
336 | QStringList children; | ||||
337 | for (auto ch : expected) { | ||||
338 | children << Utils::quote(ch, '\''); | ||||
339 | } | ||||
340 | | ||||
341 | VERIFY_LOCAL(0, "s", Utils::quote(expected), children); | ||||
241 | 342 | | |||
242 | m_session->stepOver(); | 343 | m_session->stepOver(); | ||
243 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | 344 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
244 | QCOMPARE(m_session->currentLine(), 5); | 345 | QCOMPARE(m_session->currentLine(), 5); | ||
245 | 346 | | |||
246 | VERIFY_QSTRING(0, "s", "test stringx"); | 347 | expected.append("x"); | ||
348 | children << "'x'"; | ||||
349 | | ||||
350 | VERIFY_LOCAL(0, "s", Utils::quote(expected), children); | ||||
247 | 351 | | |||
248 | m_session->run(); | 352 | m_session->run(); | ||
249 | WAIT_FOR_STATE(m_session, DebugSession::EndedState); | 353 | WAIT_FOR_STATE(m_session, DebugSession::EndedState); | ||
250 | } | 354 | } | ||
251 | /* | 355 | | ||
252 | void LldbFormattersTest::testQByteArray() | 356 | void LldbFormattersTest::testQByteArray() | ||
253 | { | 357 | { | ||
254 | LldbProcess lldb("qbytearray"); | 358 | TestLaunchConfiguration cfg("lldb_qbytearray"); | ||
255 | lldb.execute("break qbytearray.cpp:5"); | 359 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qbytearray.cpp")), 4); | ||
256 | lldb.execute("run"); | 360 | | ||
257 | QByteArray out = lldb.execute("print ba"); | 361 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
258 | QVERIFY(out.contains("\"test byte array\"")); | 362 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
259 | QVERIFY(out.contains("[0] = 116 't'")); | 363 | | ||
260 | QVERIFY(out.contains("[4] = 32 ' '")); | 364 | // Should be two rows ('auto', 'local') | ||
261 | lldb.execute("next"); | 365 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
262 | QVERIFY(lldb.execute("print ba").contains("\"test byte arrayx\"")); | 366 | | ||
367 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
368 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
369 | | ||||
370 | QStringList charlist { | ||||
371 | R"(-26 '\xe6')", | ||||
372 | R"(-104 '\x98')", | ||||
373 | R"(-81 '\xaf')", | ||||
374 | R"(39 ''')", | ||||
375 | R"(34 '"')", | ||||
376 | R"(92 '\')", | ||||
377 | R"(117 'u')", | ||||
378 | R"(54 '6')", | ||||
379 | R"(50 '2')", | ||||
380 | R"(49 '1')", | ||||
381 | R"(49 '1')", | ||||
382 | }; | ||||
383 | | ||||
384 | VERIFY_LOCAL(0, "ba", R"("\xe6\x98\xaf'\"\\u6211")", charlist); | ||||
385 | | ||||
386 | m_session->stepOver(); | ||||
387 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
388 | QCOMPARE(m_session->currentLine(), 5); | ||||
389 | | ||||
390 | charlist << "120 'x'"; | ||||
391 | VERIFY_LOCAL(0, "ba", R"("\xe6\x98\xaf'\"\\u6211x")", charlist); | ||||
392 | | ||||
393 | m_session->run(); | ||||
394 | WAIT_FOR_STATE(m_session, DebugSession::EndedState); | ||||
263 | } | 395 | } | ||
264 | 396 | | |||
397 | | ||||
265 | void LldbFormattersTest::testQListContainer_data() | 398 | void LldbFormattersTest::testQListContainer_data() | ||
266 | { | 399 | { | ||
267 | QTest::addColumn<QString>("container"); | 400 | QTest::addColumn<QString>("container"); | ||
401 | QTest::addColumn<bool>("unordered"); | ||||
268 | 402 | | |||
269 | QTest::newRow("QList") << "QList"; | 403 | QTest::newRow("QList") << "QList" << false; | ||
270 | QTest::newRow("QQueue") << "QQueue"; | 404 | QTest::newRow("QQueue") << "QQueue" << false; | ||
271 | QTest::newRow("QVector") << "QVector"; | 405 | QTest::newRow("QVector") << "QVector" << false; | ||
272 | QTest::newRow("QStack") << "QStack"; | 406 | QTest::newRow("QStack") << "QStack" << false; | ||
273 | QTest::newRow("QLinkedList") << "QLinkedList"; | 407 | QTest::newRow("QLinkedList") << "QLinkedList" << false; | ||
274 | QTest::newRow("QSet") << "QSet"; | 408 | QTest::newRow("QSet") << "QSet" << true; | ||
275 | } | 409 | } | ||
276 | 410 | | |||
277 | void LldbFormattersTest::testQListContainer() | 411 | void LldbFormattersTest::testQListContainer() | ||
278 | { | 412 | { | ||
279 | QFETCH(QString, container); | 413 | QFETCH(QString, container); | ||
280 | LldbProcess lldb("qlistcontainer"); | 414 | QFETCH(bool, unordered); | ||
281 | lldb.execute("break main"); | 415 | | ||
282 | lldb.execute("run"); | 416 | TestLaunchConfiguration cfg("lldb_qlistcontainer"); | ||
283 | lldb.execute(QString("break 'doStuff<%1>()'").arg(container).toLocal8Bit()); | 417 | cfg.config().writeEntry(KDevMI::Config::BreakOnStartEntry, true); | ||
284 | lldb.execute("cont"); | 418 | | ||
285 | { // <int> | 419 | auto watchRoot = variableCollection()->indexForItem(variableCollection()->watches(), 0); | ||
286 | lldb.execute("break qlistcontainer.cpp:34"); | 420 | variableCollection()->expanded(watchRoot); | ||
287 | lldb.execute("cont"); | 421 | variableCollection()->variableWidgetShown(); | ||
288 | QByteArray out = lldb.execute("print intList"); | 422 | | ||
289 | QVERIFY(out.contains(QString("empty %1<int>").arg(container).toLocal8Bit())); | 423 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
290 | lldb.execute("next"); | 424 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
291 | out = lldb.execute("print intList"); | 425 | | ||
292 | QVERIFY(out.contains(QString("%1<int>").arg(container).toLocal8Bit())); | 426 | m_session->addUserCommand(QString("break set --func doStuff<%1>()").arg(container)); | ||
293 | if (container != "QSet") { | 427 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||
294 | QVERIFY(out.contains("[0] = 10")); | 428 | | ||
295 | QVERIFY(out.contains("[1] = 20")); | 429 | m_session->run(); | ||
296 | QVERIFY(!out.contains("[2] = 30")); | 430 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
297 | } else { // QSet order is undefined | 431 | | ||
298 | QVERIFY(out.contains("] = 10")); | 432 | // <int> | ||
299 | QVERIFY(out.contains("] = 20")); | 433 | m_session->stepOver(); | ||
300 | QVERIFY(!out.contains("] = 30")); | 434 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
301 | } | 435 | auto var = variableCollection()->watches()->add("intList"); | ||
302 | lldb.execute("next"); | 436 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||
303 | out = lldb.execute("print intList"); | 437 | | ||
304 | QVERIFY(out.contains(QString("%1<int>").arg(container).toLocal8Bit())); | 438 | if (!verifyVariable(0, "intList", "<size=0>", QStringList{}, | ||
305 | if (container != "QSet") { | 439 | __FILE__, __LINE__, false, false, unordered)) { | ||
306 | QVERIFY(out.contains("[0] = 10")); | 440 | return; | ||
307 | QVERIFY(out.contains("[1] = 20")); | | |||
308 | QVERIFY(out.contains("[2] = 30")); | | |||
309 | } else { // QSet order is undefined | | |||
310 | QVERIFY(out.contains("] = 10")); | | |||
311 | QVERIFY(out.contains("] = 20")); | | |||
312 | QVERIFY(out.contains("] = 30")); | | |||
313 | } | | |||
314 | } | | |||
315 | { // <QString> | | |||
316 | lldb.execute("next"); | | |||
317 | QByteArray out = lldb.execute("print stringList"); | | |||
318 | QVERIFY(out.contains(QString("empty %1<QString>").arg(container).toLocal8Bit())); | | |||
319 | lldb.execute("next"); | | |||
320 | out = lldb.execute("print stringList"); | | |||
321 | QVERIFY(out.contains(QString("%1<QString>").arg(container).toLocal8Bit())); | | |||
322 | if (container != "QSet") { | | |||
323 | QVERIFY(out.contains("[0] = \"a\"")); | | |||
324 | QVERIFY(out.contains("[1] = \"bc\"")); | | |||
325 | QVERIFY(!out.contains("[2] = \"d\"")); | | |||
326 | } else { // QSet order is undefined | | |||
327 | QVERIFY(out.contains("] = \"a\"")); | | |||
328 | QVERIFY(out.contains("] = \"bc\"")); | | |||
329 | QVERIFY(!out.contains("] = \"d\"")); | | |||
330 | } | | |||
331 | lldb.execute("next"); | | |||
332 | out = lldb.execute("print stringList"); | | |||
333 | QVERIFY(out.contains(QString("%1<QString>").arg(container).toLocal8Bit())); | | |||
334 | if (container != "QSet") { | | |||
335 | QVERIFY(out.contains("[0] = \"a\"")); | | |||
336 | QVERIFY(out.contains("[1] = \"bc\"")); | | |||
337 | QVERIFY(out.contains("[2] = \"d\"")); | | |||
338 | } else { // QSet order is undefined | | |||
339 | QVERIFY(out.contains("] = \"a\"")); | | |||
340 | QVERIFY(out.contains("] = \"bc\"")); | | |||
341 | QVERIFY(out.contains("] = \"d\"")); | | |||
342 | } | | |||
343 | } | | |||
344 | { // <struct A> | | |||
345 | lldb.execute("next"); | | |||
346 | QByteArray out = lldb.execute("print structList"); | | |||
347 | QVERIFY(out.contains(QString("empty %1<A>").arg(container).toLocal8Bit())); | | |||
348 | lldb.execute("next"); | | |||
349 | out = lldb.execute("print structList"); | | |||
350 | QVERIFY(out.contains(QString("%1<A>").arg(container).toLocal8Bit())); | | |||
351 | QVERIFY(out.contains("[0] = {")); | | |||
352 | QVERIFY(out.contains("a = \"a\"")); | | |||
353 | QVERIFY(out.contains("b = \"b\"")); | | |||
354 | QVERIFY(out.contains("c = 100")); | | |||
355 | QVERIFY(out.contains("d = -200")); | | |||
356 | lldb.execute("next"); | | |||
357 | out = lldb.execute("print structList"); | | |||
358 | QVERIFY(out.contains(QString("%1<A>").arg(container).toLocal8Bit())); | | |||
359 | QVERIFY(out.contains("[1] = {")); | | |||
360 | } | | |||
361 | { // <int*> | | |||
362 | lldb.execute("next"); | | |||
363 | QByteArray out = lldb.execute("print pointerList"); | | |||
364 | QVERIFY(out.contains(QString("empty %1<int *>").arg(container).toLocal8Bit())); | | |||
365 | lldb.execute("next"); | | |||
366 | out = lldb.execute("print pointerList"); | | |||
367 | QVERIFY(out.contains(QString("%1<int *>").arg(container).toLocal8Bit())); | | |||
368 | QVERIFY(out.contains("[0] = 0x")); | | |||
369 | QVERIFY(out.contains("[1] = 0x")); | | |||
370 | QVERIFY(!out.contains("[2] = 0x")); | | |||
371 | lldb.execute("next"); | | |||
372 | out = lldb.execute("print pointerList"); | | |||
373 | QVERIFY(out.contains("[0] = 0x")); | | |||
374 | QVERIFY(out.contains("[1] = 0x")); | | |||
375 | QVERIFY(out.contains("[2] = 0x")); | | |||
376 | lldb.execute("next"); | | |||
377 | } | | |||
378 | { // <QPair<int, int> > | | |||
379 | lldb.execute("next"); | | |||
380 | QByteArray out = lldb.execute("print pairList"); | | |||
381 | QVERIFY(out.contains(QString("empty %1<QPair<int, int>>").arg(container).toLocal8Bit())); | | |||
382 | lldb.execute("next"); | | |||
383 | out = lldb.execute("print pairList"); | | |||
384 | QVERIFY(out.contains(QString("%1<QPair<int, int>>").arg(container).toLocal8Bit())); | | |||
385 | if (container != "QSet") { | | |||
386 | QVERIFY(out.contains("[0] = {\n first = 1, \n second = 2\n }")); | | |||
387 | QVERIFY(out.contains("[1] = {\n first = 2, \n second = 3\n }")); | | |||
388 | } else { // order is undefined in QSet | | |||
389 | QVERIFY(out.contains("] = {\n first = 1, \n second = 2\n }")); | | |||
390 | QVERIFY(out.contains("] = {\n first = 2, \n second = 3\n }")); | | |||
391 | } | | |||
392 | QVERIFY(!out.contains("[2] = ")); | | |||
393 | lldb.execute("next"); | | |||
394 | out = lldb.execute("print pairList"); | | |||
395 | if (container != "QSet") { | | |||
396 | QVERIFY(out.contains("[0] = {\n first = 1, \n second = 2\n }")); | | |||
397 | QVERIFY(out.contains("[1] = {\n first = 2, \n second = 3\n }")); | | |||
398 | QVERIFY(out.contains("[2] = {\n first = 4, \n second = 5\n }")); | | |||
399 | } else { // order is undefined in QSet | | |||
400 | QVERIFY(out.contains("] = {\n first = 1, \n second = 2\n }")); | | |||
401 | QVERIFY(out.contains("] = {\n first = 2, \n second = 3\n }")); | | |||
402 | QVERIFY(out.contains("] = {\n first = 4, \n second = 5\n }")); | | |||
403 | } | 441 | } | ||
442 | | ||||
443 | m_session->stepOver(); | ||||
444 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
445 | | ||||
446 | variableCollection()->expanded(watchVariableIndexAt(0)); // expand this node for correct update. | ||||
447 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
448 | | ||||
449 | if (!verifyVariable(0, "intList", "<size=2>", QStringList{"10", "20"}, | ||||
450 | __FILE__, __LINE__, false, false, unordered)) { | ||||
451 | return; | ||||
404 | } | 452 | } | ||
453 | | ||||
454 | m_session->stepOver(); | ||||
455 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
456 | | ||||
457 | if (!verifyVariable(0, "intList", "<size=3>", QStringList{"10", "20", "30"}, | ||||
458 | __FILE__, __LINE__, false, false, unordered)) { | ||||
459 | return; | ||||
405 | } | 460 | } | ||
461 | var->die(); | ||||
406 | 462 | | |||
407 | void LldbFormattersTest::testQMapInt() | 463 | // <QString> | ||
408 | { | 464 | m_session->stepOver(); | ||
409 | LldbProcess lldb("qmapint"); | 465 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
410 | lldb.execute("break qmapint.cpp:7"); | 466 | var = variableCollection()->watches()->add("stringList"); | ||
411 | lldb.execute("run"); | 467 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||
412 | QByteArray out = lldb.execute("print m"); | 468 | | ||
413 | QVERIFY(out.contains("QMap<int, int>")); | 469 | if (!verifyVariable(0, "stringList", "<size=0>", QStringList{}, | ||
414 | QVERIFY(out.contains("[10] = 100")); | 470 | __FILE__, __LINE__, false, false, unordered)) { | ||
415 | QVERIFY(out.contains("[20] = 200")); | 471 | return; | ||
416 | lldb.execute("next"); | | |||
417 | out = lldb.execute("print m"); | | |||
418 | QVERIFY(out.contains("[30] = 300")); | | |||
419 | } | 472 | } | ||
420 | 473 | | |||
421 | void LldbFormattersTest::testQMapString() | 474 | m_session->stepOver(); | ||
422 | { | 475 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
423 | LldbProcess lldb("qmapstring"); | 476 | | ||
424 | lldb.execute("break qmapstring.cpp:8"); | 477 | variableCollection()->expanded(watchVariableIndexAt(0)); // expand this node for correct update. | ||
425 | lldb.execute("run"); | 478 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||
426 | QByteArray out = lldb.execute("print m"); | 479 | | ||
427 | QVERIFY(out.contains("QMap<QString, QString>")); | 480 | | ||
428 | QVERIFY(out.contains("[\"10\"] = \"100\"")); | 481 | if (!verifyVariable(0, "stringList", "<size=2>", QStringList{"\"a\"", "\"bc\""}, | ||
429 | QVERIFY(out.contains("[\"20\"] = \"200\"")); | 482 | __FILE__, __LINE__, false, false, unordered)) { | ||
430 | lldb.execute("next"); | 483 | return; | ||
431 | out = lldb.execute("print m"); | | |||
432 | QVERIFY(out.contains("[\"30\"] = \"300\"")); | | |||
433 | } | 484 | } | ||
434 | 485 | | |||
435 | void LldbFormattersTest::testQMapStringBool() | 486 | m_session->stepOver(); | ||
436 | { | 487 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
437 | LldbProcess lldb("qmapstringbool"); | 488 | | ||
438 | lldb.execute("break qmapstringbool.cpp:8"); | 489 | if (!verifyVariable(0, "stringList", "<size=3>", QStringList{"\"a\"", "\"bc\"", "\"d\""}, | ||
439 | lldb.execute("run"); | 490 | __FILE__, __LINE__, false, false, unordered)) { | ||
440 | QByteArray out = lldb.execute("print m"); | 491 | return; | ||
441 | QVERIFY(out.contains("QMap<QString, bool>")); | | |||
442 | QVERIFY(out.contains("[\"10\"] = true")); | | |||
443 | QVERIFY(out.contains("[\"20\"] = false")); | | |||
444 | lldb.execute("next"); | | |||
445 | out = lldb.execute("print m"); | | |||
446 | QVERIFY(out.contains("[\"30\"] = true")); | | |||
447 | } | 492 | } | ||
493 | var->die(); | ||||
494 | | ||||
495 | // <struct A> | ||||
496 | m_session->stepOver(); | ||||
497 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
498 | var = variableCollection()->watches()->add("structList"); | ||||
499 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
448 | 500 | | |||
501 | if (!verifyVariable(0, "structList", "<size=0>", QStringList{}, | ||||
502 | __FILE__, __LINE__, false, false, unordered)) { | ||||
503 | return; | ||||
504 | } | ||||
449 | 505 | | |||
450 | void LldbFormattersTest::testQDate() | 506 | m_session->stepOver(); | ||
507 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
508 | | ||||
509 | variableCollection()->expanded(watchVariableIndexAt(0)); // expand this node for correct update. | ||||
510 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
511 | | ||||
512 | if (!verifyVariable(0, "structList", "<size=1>", QStringList{"{...}"}, | ||||
513 | __FILE__, __LINE__, false, false, unordered)) { | ||||
514 | return; | ||||
515 | } | ||||
516 | | ||||
517 | m_session->stepOver(); | ||||
518 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
519 | | ||||
520 | if (!verifyVariable(0, "structList", "<size=2>", QStringList{"{...}", "{...}"}, | ||||
521 | __FILE__, __LINE__, false, false, unordered)) { | ||||
522 | return; | ||||
523 | } | ||||
524 | var->die(); | ||||
525 | | ||||
526 | // <int*> | ||||
527 | m_session->stepOver(); | ||||
528 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
529 | var = variableCollection()->watches()->add("pointerList"); | ||||
530 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
531 | | ||||
532 | if (!verifyVariable(0, "pointerList", "<size=0>", QStringList{}, | ||||
533 | __FILE__, __LINE__, false, false, unordered)) { | ||||
534 | return; | ||||
535 | } | ||||
536 | | ||||
537 | m_session->stepOver(); | ||||
538 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
539 | | ||||
540 | variableCollection()->expanded(watchVariableIndexAt(0)); // expand this node for correct update. | ||||
541 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
542 | | ||||
543 | if (!verifyVariable(0, "pointerList", "<size=2>", QStringList{"^0x[0-9A-Fa-f]+$", "^0x[0-9A-Fa-f]+$"}, | ||||
544 | __FILE__, __LINE__, false, true, unordered)) { | ||||
545 | return; | ||||
546 | } | ||||
547 | | ||||
548 | m_session->stepOver(); | ||||
549 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
550 | | ||||
551 | if (!verifyVariable(0, "pointerList", "<size=3>", QStringList{"^0x[0-9A-Fa-f]+$", "^0x[0-9A-Fa-f]+$", | ||||
552 | "^0x[0-9A-Fa-f]+$"}, | ||||
553 | __FILE__, __LINE__, false, true, unordered)) { | ||||
554 | return; | ||||
555 | } | ||||
556 | var->die(); | ||||
557 | m_session->stepOver(); // step over qDeleteAll | ||||
558 | | ||||
559 | // <QPair<int, int>> | ||||
560 | m_session->stepOver(); | ||||
561 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
562 | var = variableCollection()->watches()->add("pairList"); | ||||
563 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
564 | | ||||
565 | VERIFY_WATCH(0, "pairList", "<size=0>", QStringList{}); | ||||
566 | | ||||
567 | m_session->stepOver(); | ||||
568 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
569 | | ||||
570 | variableCollection()->expanded(watchVariableIndexAt(0)); // expand this node for correct update. | ||||
571 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
572 | | ||||
573 | if (!verifyVariable(0, "pairList", "<size=2>", QStringList{"{...}", "{...}"}, | ||||
574 | __FILE__, __LINE__, false, false, unordered)) { | ||||
575 | return; | ||||
576 | } | ||||
577 | | ||||
578 | m_session->stepOver(); | ||||
579 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
580 | | ||||
581 | if (!verifyVariable(0, "pairList", "<size=3>", QStringList{"{...}", "{...}", "{...}"}, | ||||
582 | __FILE__, __LINE__, false, false, unordered)) { | ||||
583 | return; | ||||
584 | } | ||||
585 | var->die(); | ||||
586 | } | ||||
587 | | ||||
588 | void LldbFormattersTest::testQListPOD() | ||||
451 | { | 589 | { | ||
452 | LldbProcess lldb("qdate"); | 590 | TestLaunchConfiguration cfg("lldb_qlistpod"); | ||
453 | lldb.execute("break qdate.cpp:6"); | 591 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qlistpod.cpp")), 30); | ||
454 | lldb.execute("run"); | 592 | | ||
455 | QByteArray out = lldb.execute("print d"); | 593 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
456 | QVERIFY(out.contains("2010-01-20")); | 594 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
595 | | ||||
596 | // Should be two rows ('auto', 'local') | ||||
597 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
598 | | ||||
599 | auto watchRoot = variableCollection()->indexForItem(variableCollection()->watches(), 0); | ||||
600 | variableCollection()->expanded(watchRoot); | ||||
601 | variableCollection()->variableWidgetShown(); | ||||
602 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
603 | | ||||
604 | variableCollection()->watches()->add("b"); | ||||
605 | variableCollection()->watches()->add("c"); | ||||
606 | variableCollection()->watches()->add("uc"); | ||||
607 | variableCollection()->watches()->add("s"); | ||||
608 | variableCollection()->watches()->add("us"); | ||||
609 | variableCollection()->watches()->add("i"); | ||||
610 | variableCollection()->watches()->add("ui"); | ||||
611 | variableCollection()->watches()->add("l"); | ||||
612 | variableCollection()->watches()->add("ul"); | ||||
613 | variableCollection()->watches()->add("i64"); | ||||
614 | variableCollection()->watches()->add("ui64"); | ||||
615 | variableCollection()->watches()->add("f"); | ||||
616 | variableCollection()->watches()->add("d"); | ||||
617 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
618 | | ||||
619 | VERIFY_WATCH(0, "b", "<size=1>", (QStringList{"false"})); | ||||
620 | VERIFY_WATCH(1, "c", "<size=1>", (QStringList{"50 '2'"})); | ||||
621 | VERIFY_WATCH(2, "uc", "<size=1>", (QStringList{"50 '2'"})); | ||||
622 | | ||||
623 | VERIFY_WATCH(3, "s", "<size=1>", (QStringList{"50"})); | ||||
624 | VERIFY_WATCH(4, "us", "<size=1>", (QStringList{"50"})); | ||||
625 | | ||||
626 | VERIFY_WATCH(5, "i", "<size=1>", (QStringList{"50"})); | ||||
627 | VERIFY_WATCH(6, "ui", "<size=1>", (QStringList{"50"})); | ||||
628 | | ||||
629 | VERIFY_WATCH(7, "l", "<size=1>", (QStringList{"50"})); | ||||
630 | VERIFY_WATCH(8, "ul", "<size=1>", (QStringList{"50"})); | ||||
631 | | ||||
632 | VERIFY_WATCH(9, "i64", "<size=1>", (QStringList{"50"})); | ||||
633 | VERIFY_WATCH(10, "ui64", "<size=1>", (QStringList{"50"})); | ||||
634 | | ||||
635 | VERIFY_WATCH(11, "f", "<size=1>", (QStringList{"50"})); | ||||
636 | VERIFY_WATCH(12, "d", "<size=1>", (QStringList{"50"})); | ||||
457 | } | 637 | } | ||
458 | 638 | | |||
459 | void LldbFormattersTest::testQTime() | 639 | void LldbFormattersTest::testQMapInt() | ||
460 | { | 640 | { | ||
461 | LldbProcess lldb("qtime"); | 641 | TestLaunchConfiguration cfg("lldb_qmapint"); | ||
462 | lldb.execute("break qtime.cpp:6"); | 642 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qmapint.cpp")), 6); | ||
463 | lldb.execute("run"); | 643 | | ||
464 | QByteArray out = lldb.execute("print t"); | 644 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
465 | QVERIFY(out.contains("15:30:10.123")); | 645 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
646 | | ||||
647 | // Should be two rows ('auto', 'local') | ||||
648 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
649 | | ||||
650 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
651 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
652 | | ||||
653 | VERIFY_LOCAL(0, "m", "<size=2>", (QStringList{"(10, 100)", "(20, 200)"})); | ||||
654 | | ||||
655 | m_session->stepOver(); | ||||
656 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
657 | QCOMPARE(m_session->currentLine(), 7); | ||||
658 | | ||||
659 | VERIFY_LOCAL(0, "m", "<size=3>", (QStringList{"(10, 100)", "(20, 200)", "(30, 300)"})); | ||||
466 | } | 660 | } | ||
467 | 661 | | |||
468 | void LldbFormattersTest::testQDateTime() | 662 | void LldbFormattersTest::testQMapString() | ||
469 | { | 663 | { | ||
470 | LldbProcess lldb("qdatetime"); | 664 | TestLaunchConfiguration cfg("lldb_qmapstring"); | ||
471 | lldb.execute("break qdatetime.cpp:5"); | 665 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qmapstring.cpp")), 7); | ||
472 | lldb.execute("run"); | 666 | | ||
473 | QByteArray out = lldb.execute("print dt"); | 667 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
474 | QVERIFY(out.contains("Wed Jan 20 15:31:13 2010")); | 668 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
669 | | ||||
670 | // Should be two rows ('auto', 'local') | ||||
671 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
672 | | ||||
673 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
674 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
675 | | ||||
676 | VERIFY_LOCAL(0, "m", "<size=2>", (QStringList{"(\"10\", \"100\")", "(\"20\", \"200\")"})); | ||||
677 | | ||||
678 | m_session->stepOver(); | ||||
679 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
680 | QCOMPARE(m_session->currentLine(), 8); | ||||
681 | | ||||
682 | VERIFY_LOCAL(0, "m", "<size=3>", | ||||
683 | (QStringList{"(\"10\", \"100\")", "(\"20\", \"200\")", "(\"30\", \"300\")"})); | ||||
475 | } | 684 | } | ||
476 | 685 | | |||
477 | void LldbFormattersTest::testQUrl() | 686 | void LldbFormattersTest::testQMapStringBool() | ||
478 | { | 687 | { | ||
479 | LldbProcess lldb("qurl"); | 688 | TestLaunchConfiguration cfg("lldb_qmapstringbool"); | ||
480 | lldb.execute("break qurl.cpp:5"); | 689 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qmapstringbool.cpp")), 7); | ||
481 | lldb.execute("run"); | 690 | | ||
482 | QByteArray out = lldb.execute("print u"); | 691 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
483 | QVERIFY(out.contains("http://www.kdevelop.org/foo")); | 692 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
693 | | ||||
694 | // Should be two rows ('auto', 'local') | ||||
695 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
696 | | ||||
697 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
698 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
699 | | ||||
700 | VERIFY_LOCAL(0, "m", "<size=2>", (QStringList{"(\"10\", true)", "(\"20\", false)"})); | ||||
701 | | ||||
702 | m_session->stepOver(); | ||||
703 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
704 | QCOMPARE(m_session->currentLine(), 8); | ||||
705 | | ||||
706 | VERIFY_LOCAL(0, "m", "<size=3>", (QStringList{"(\"10\", true)", "(\"20\", false)", "(\"30\", true)"})); | ||||
484 | } | 707 | } | ||
485 | 708 | | |||
709 | | ||||
486 | void LldbFormattersTest::testQHashInt() | 710 | void LldbFormattersTest::testQHashInt() | ||
487 | { | 711 | { | ||
488 | LldbProcess lldb("qhashint"); | 712 | TestLaunchConfiguration cfg("lldb_qhashint"); | ||
489 | lldb.execute("break qhashint.cpp:7"); | 713 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qhashint.cpp")), 6); | ||
490 | lldb.execute("run"); | 714 | | ||
491 | QByteArray out = lldb.execute("print h"); | 715 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
492 | QVERIFY(out.contains("[10] = 100")); | 716 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
493 | QVERIFY(out.contains("[20] = 200")); | 717 | | ||
494 | lldb.execute("next"); | 718 | // Should be two rows ('auto', 'local') | ||
495 | out = lldb.execute("print h"); | 719 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
496 | QVERIFY(out.contains("[30] = 300")); | 720 | | ||
721 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
722 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
723 | | ||||
724 | if (!verifyVariable(0, "h", "<size=2>", {"(10, 100)", "(20, 200)"}, | ||||
725 | __FILE__, __LINE__, true, false, true)) { | ||||
726 | return; | ||||
727 | } | ||||
728 | | ||||
729 | m_session->stepOver(); | ||||
730 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
731 | QCOMPARE(m_session->currentLine(), 7); | ||||
732 | | ||||
733 | if (!verifyVariable(0, "h", "<size=3>", {"(10, 100)", "(20, 200)", "(30, 300)"}, | ||||
734 | __FILE__, __LINE__, true, false, true)) { | ||||
735 | return; | ||||
736 | } | ||||
497 | } | 737 | } | ||
498 | 738 | | |||
499 | void LldbFormattersTest::testQHashString() | 739 | void LldbFormattersTest::testQHashString() | ||
500 | { | 740 | { | ||
501 | LldbProcess lldb("qhashstring"); | 741 | TestLaunchConfiguration cfg("lldb_qhashstring"); | ||
502 | lldb.execute("break qhashstring.cpp:8"); | 742 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qhashstring.cpp")), 7); | ||
503 | lldb.execute("run"); | 743 | | ||
504 | QByteArray out = lldb.execute("print h"); | 744 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
505 | QVERIFY(out.contains("[\"10\"] = \"100\"")); | 745 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
506 | QVERIFY(out.contains("[\"20\"] = \"200\"")); | 746 | | ||
507 | lldb.execute("next"); | 747 | // Should be two rows ('auto', 'local') | ||
508 | out = lldb.execute("print h"); | 748 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
509 | QVERIFY(out.contains("[\"30\"] = \"300\"")); | 749 | | ||
750 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
751 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
752 | | ||||
753 | if (!verifyVariable(0, "h", "<size=2>", {"(\"10\", \"100\")", "(\"20\", \"200\")"}, | ||||
754 | __FILE__, __LINE__, true, false, true)) { | ||||
755 | return; | ||||
756 | } | ||||
757 | | ||||
758 | m_session->stepOver(); | ||||
759 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
760 | QCOMPARE(m_session->currentLine(), 8); | ||||
761 | | ||||
762 | if (!verifyVariable(0, "h", "<size=3>", | ||||
763 | {"(\"10\", \"100\")", "(\"20\", \"200\")", "(\"30\", \"300\")"}, | ||||
764 | __FILE__, __LINE__, true, false, true)) { | ||||
765 | return; | ||||
766 | } | ||||
510 | } | 767 | } | ||
511 | 768 | | |||
512 | void LldbFormattersTest::testQSetInt() | 769 | void LldbFormattersTest::testQSetInt() | ||
513 | { | 770 | { | ||
514 | LldbProcess lldb("qsetint"); | 771 | TestLaunchConfiguration cfg("lldb_qsetint"); | ||
515 | lldb.execute("break qsetint.cpp:7"); | 772 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qsetint.cpp")), 6); | ||
516 | lldb.execute("run"); | 773 | | ||
517 | QByteArray out = lldb.execute("print s"); | 774 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
518 | QVERIFY(out.contains("] = 10")); | 775 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
519 | QVERIFY(out.contains("] = 20")); | 776 | | ||
520 | lldb.execute("next"); | 777 | // Should be two rows ('auto', 'local') | ||
521 | out = lldb.execute("print s"); | 778 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
522 | QVERIFY(out.contains("] = 30")); | 779 | | ||
780 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
781 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
782 | | ||||
783 | if (!verifyVariable(0, "s", "<size=2>", {"10", "20"}, | ||||
784 | __FILE__, __LINE__, true, false, true)) { | ||||
785 | return; | ||||
786 | } | ||||
787 | | ||||
788 | m_session->stepOver(); | ||||
789 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
790 | QCOMPARE(m_session->currentLine(), 7); | ||||
791 | | ||||
792 | if (!verifyVariable(0, "s", "<size=3>", {"10", "20", "30"}, | ||||
793 | __FILE__, __LINE__, true, false, true)) { | ||||
794 | return; | ||||
795 | } | ||||
523 | } | 796 | } | ||
524 | 797 | | |||
525 | void LldbFormattersTest::testQSetString() | 798 | void LldbFormattersTest::testQSetString() | ||
526 | { | 799 | { | ||
527 | LldbProcess lldb("qsetstring"); | 800 | TestLaunchConfiguration cfg("lldb_qsetstring"); | ||
528 | lldb.execute("break qsetstring.cpp:8"); | 801 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qsetstring.cpp")), 7); | ||
529 | lldb.execute("run"); | 802 | | ||
530 | QByteArray out = lldb.execute("print s"); | 803 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
531 | QVERIFY(out.contains("] = \"10\"")); | 804 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
532 | QVERIFY(out.contains("] = \"20\"")); | 805 | | ||
533 | lldb.execute("next"); | 806 | // Should be two rows ('auto', 'local') | ||
534 | out = lldb.execute("print s"); | 807 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
535 | QVERIFY(out.contains("] = \"30\"")); | 808 | | ||
809 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
810 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
811 | | ||||
812 | if (!verifyVariable(0, "s", "<size=2>", {"\"10\"", "\"20\""}, | ||||
813 | __FILE__, __LINE__, true, false, true)) { | ||||
814 | return; | ||||
536 | } | 815 | } | ||
537 | 816 | | |||
538 | void LldbFormattersTest::testQChar() | 817 | m_session->stepOver(); | ||
818 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
819 | QCOMPARE(m_session->currentLine(), 8); | ||||
820 | | ||||
821 | if (!verifyVariable(0, "s", "<size=3>", | ||||
822 | {"\"10\"", "\"20\"", "\"30\""}, | ||||
823 | __FILE__, __LINE__, true, false, true)) { | ||||
824 | return; | ||||
825 | } | ||||
826 | } | ||||
827 | | ||||
828 | void LldbFormattersTest::testQDate() | ||||
539 | { | 829 | { | ||
540 | LldbProcess lldb("qchar"); | 830 | TestLaunchConfiguration cfg("lldb_qdate"); | ||
541 | lldb.execute("break qchar.cpp:5"); | 831 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qdate.cpp")), 5); | ||
542 | lldb.execute("run"); | 832 | | ||
543 | QVERIFY(lldb.execute("print c").contains("\"k\"")); | 833 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
834 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
835 | | ||||
836 | // Should be two rows ('auto', 'local') | ||||
837 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
838 | | ||||
839 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
840 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
841 | | ||||
842 | QList<QPair<QString, QString>> children; | ||||
843 | children.append({"jd", "2455217"}); | ||||
844 | children.append({"(ISO)", "\"2010-01-20\""}); | ||||
845 | children.append({"(Locale)", "\".+\""}); // (Locale) and summary are locale dependent | ||||
846 | if (!verifyVariable(0, "d", ".+", children, | ||||
847 | __FILE__, __LINE__, true, true, false)) { | ||||
848 | return; | ||||
849 | } | ||||
544 | } | 850 | } | ||
545 | 851 | | |||
546 | void LldbFormattersTest::testQListPOD() | 852 | void LldbFormattersTest::testQTime() | ||
853 | { | ||||
854 | TestLaunchConfiguration cfg("lldb_qtime"); | ||||
855 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qtime.cpp")), 5); | ||||
856 | | ||||
857 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||||
858 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
859 | | ||||
860 | // Should be two rows ('auto', 'local') | ||||
861 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
862 | | ||||
863 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
864 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
865 | | ||||
866 | QList<QPair<QString, QString>> children; | ||||
867 | children.append({"mds", "55810123"}); | ||||
868 | children.append({"(ISO)", "\"15:30:10.000123\""}); | ||||
869 | children.append({"(Locale)", "\".+\""}); // (Locale) and summary are locale dependent | ||||
870 | if (!verifyVariable(0, "t", ".+", children, | ||||
871 | __FILE__, __LINE__, true, true, false)) { | ||||
872 | return; | ||||
873 | } | ||||
874 | } | ||||
875 | | ||||
876 | void LldbFormattersTest::testQDateTime() | ||||
877 | { | ||||
878 | TestLaunchConfiguration cfg("lldb_qdatetime"); | ||||
879 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qdatetime.cpp")), 5); | ||||
880 | | ||||
881 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||||
882 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||||
883 | | ||||
884 | // Should be two rows ('auto', 'local') | ||||
885 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
886 | | ||||
887 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
888 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
889 | | ||||
890 | QList<QPair<QString, QString>> children; | ||||
891 | children.append({"toTime_t", "1264019473"}); | ||||
892 | children.append({"(ISO)", "\"2010-01-20 20:31:13\""}); | ||||
893 | children.append({"(Locale)", "\".+\""}); // (Locale), (UTC) and summary are locale dependent | ||||
894 | children.append({"(UTC)", "\".+\""}); | ||||
895 | if (!verifyVariable(0, "dt", ".+", children, | ||||
896 | __FILE__, __LINE__, true, true, false)) { | ||||
897 | return; | ||||
898 | } | ||||
899 | } | ||||
900 | | ||||
901 | void LldbFormattersTest::testQUrl() | ||||
547 | { | 902 | { | ||
548 | LldbProcess lldb("qlistpod"); | 903 | TestLaunchConfiguration cfg("lldb_qurl"); | ||
549 | lldb.execute("break qlistpod.cpp:31"); | 904 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("qurl.cpp")), 4); | ||
550 | lldb.execute("run"); | 905 | | ||
551 | QVERIFY(lldb.execute("print b").contains("false")); | 906 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
552 | QVERIFY(lldb.execute("print c").contains("50")); | 907 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
553 | QVERIFY(lldb.execute("print uc").contains("50")); | 908 | | ||
554 | QVERIFY(lldb.execute("print s").contains("50")); | 909 | // Should be two rows ('auto', 'local') | ||
555 | QVERIFY(lldb.execute("print us").contains("50")); | 910 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
556 | QVERIFY(lldb.execute("print i").contains("50")); | 911 | | ||
557 | QVERIFY(lldb.execute("print ui").contains("50")); | 912 | variableCollection()->expanded(localVariableIndexAt(0)); | ||
558 | QVERIFY(lldb.execute("print l").contains("50")); | 913 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||
559 | QVERIFY(lldb.execute("print ul").contains("50")); | 914 | | ||
560 | QVERIFY(lldb.execute("print i64").contains("50")); | 915 | QList<QPair<QString, QString>> children; | ||
561 | QVERIFY(lldb.execute("print ui64").contains("50")); | 916 | children.append({"(port)", "-1"}); | ||
562 | QVERIFY(lldb.execute("print f").contains("50")); | 917 | children.append({"(scheme)", "\"http\""}); | ||
563 | QVERIFY(lldb.execute("print d").contains("50")); | 918 | children.append({"(userName)", "<Invalid>"}); | ||
919 | children.append({"(password)", "<Invalid>"}); | ||||
920 | children.append({"(host)", "\"www.kdevelop.org\""}); | ||||
921 | children.append({"(path)", "\"/foo\""}); | ||||
922 | children.append({"(query)", "<Invalid>"}); | ||||
923 | children.append({"(fragment)", "<Invalid>"}); | ||||
924 | VERIFY_LOCAL(0, "u", "\"http://www.kdevelop.org/foo\"", children); | ||||
564 | } | 925 | } | ||
565 | 926 | | |||
566 | void LldbFormattersTest::testQUuid() | 927 | void LldbFormattersTest::testQUuid() | ||
567 | { | 928 | { | ||
568 | LldbProcess lldb("quuid"); | 929 | TestLaunchConfiguration cfg("lldb_quuid"); | ||
569 | lldb.execute("break quuid.cpp:4"); | 930 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("quuid.cpp")), 4); | ||
570 | lldb.execute("run"); | 931 | | ||
571 | QByteArray data = lldb.execute("print id"); | 932 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
572 | QVERIFY(data.contains("{9ec3b70b-d105-42bf-b3b4-656e44d2e223}")); | 933 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
934 | | ||||
935 | // Should be two rows ('auto', 'local') | ||||
936 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
937 | | ||||
938 | variableCollection()->expanded(localVariableIndexAt(0)); | ||||
939 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
940 | | ||||
941 | VERIFY_LOCAL(0, "id", "QUuid({9ec3b70b-d105-42bf-b3b4-656e44d2e223})", (QStringList{})); | ||||
573 | } | 942 | } | ||
574 | 943 | | |||
575 | void LldbFormattersTest::testKTextEditorTypes() | 944 | void LldbFormattersTest::testKTextEditorTypes() | ||
576 | { | 945 | { | ||
577 | LldbProcess lldb("ktexteditortypes"); | 946 | TestLaunchConfiguration cfg("lldb_ktexteditortypes"); | ||
578 | lldb.execute("break ktexteditortypes.cpp:9"); | 947 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("ktexteditortypes.cpp")), 8); | ||
579 | lldb.execute("run"); | 948 | | ||
580 | 949 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | |||
581 | QByteArray data = lldb.execute("print cursor"); | 950 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
582 | QCOMPARE(data, QByteArray("$1 = [1, 1]")); | 951 | | ||
583 | data = lldb.execute("print range"); | 952 | // Should be two rows ('auto', 'local') | ||
584 | QCOMPARE(data, QByteArray("$2 = [(1, 1) -> (2, 2)]")); | 953 | QCOMPARE(variableCollection()->rowCount(), 2); | ||
954 | | ||||
955 | auto watchRoot = variableCollection()->indexForItem(variableCollection()->watches(), 0); | ||||
956 | variableCollection()->expanded(watchRoot); | ||||
957 | variableCollection()->variableWidgetShown(); | ||||
958 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
959 | | ||||
960 | variableCollection()->watches()->add("cursor"); | ||||
961 | variableCollection()->watches()->add("range"); | ||||
962 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
963 | | ||||
964 | QList<QPair<QString, QString>> cursorChildren; | ||||
965 | cursorChildren.append({"m_line", "1"}); | ||||
966 | cursorChildren.append({"m_column", "1"}); | ||||
967 | | ||||
968 | QList<QPair<QString, QString>> rangeChildren; | ||||
969 | rangeChildren.append({"m_start", "(1, 1)"}); | ||||
970 | rangeChildren.append({"m_end", "(2, 2)"}); | ||||
971 | | ||||
972 | VERIFY_WATCH(0, "cursor", "(1, 1)", cursorChildren); | ||||
973 | VERIFY_WATCH(1, "range", "[(1, 1) -> (2, 2)]", rangeChildren); | ||||
585 | } | 974 | } | ||
586 | 975 | | |||
587 | void LldbFormattersTest::testKDevelopTypes() | 976 | void LldbFormattersTest::testKDevelopTypes() | ||
588 | { | 977 | { | ||
589 | LldbProcess lldb("kdeveloptypes"); | 978 | TestLaunchConfiguration cfg("lldb_kdeveloptypes"); | ||
590 | lldb.execute("break kdeveloptypes.cpp:12"); | 979 | addCodeBreakpoint(QUrl::fromLocalFile(findSourceFile("kdeveloptypes.cpp")), 11); | ||
591 | lldb.execute("run"); | | |||
592 | 980 | | |||
593 | QVERIFY(lldb.execute("print path1").contains("(\"tmp\", \"foo\")")); | 981 | QVERIFY(m_session->startDebugging(&cfg, m_iface)); | ||
594 | QVERIFY(lldb.execute("print path2").contains("(\"http://www.test.com\", \"tmp\", \"asdf.txt\")")); | 982 | WAIT_FOR_STATE_AND_IDLE(m_session, DebugSession::PausedState); | ||
983 | | ||||
984 | // Should be two rows ('auto', 'local') | ||||
985 | QCOMPARE(variableCollection()->rowCount(), 2); | ||||
986 | | ||||
987 | auto watchRoot = variableCollection()->indexForItem(variableCollection()->watches(), 0); | ||||
988 | variableCollection()->expanded(watchRoot); | ||||
989 | variableCollection()->variableWidgetShown(); | ||||
990 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
991 | | ||||
992 | variableCollection()->watches()->add("path1"); | ||||
993 | variableCollection()->watches()->add("path2"); | ||||
994 | WAIT_FOR_A_WHILE_AND_IDLE(m_session, 50); | ||||
995 | | ||||
996 | QList<QPair<QString, QString>> path1Children; | ||||
997 | path1Children.append({"m_data", "<size=2>"}); | ||||
998 | | ||||
999 | QList<QPair<QString, QString>> path2Children; | ||||
1000 | path2Children.append({"m_data", "<size=3>"}); | ||||
1001 | | ||||
1002 | VERIFY_WATCH(0, "path1", "(\"tmp\", \"foo\")", path1Children); | ||||
1003 | VERIFY_WATCH(1, "path2", "(\"http://www.test.com\", \"tmp\", \"asdf.txt\")", path2Children); | ||||
595 | } | 1004 | } | ||
596 | */ | | |||
597 | 1005 | | |||
598 | QTEST_MAIN(LldbFormattersTest) | 1006 | QTEST_MAIN(LldbFormattersTest) | ||
599 | 1007 | | |||
600 | #include "test_lldbformatters.moc" | 1008 | #include "test_lldbformatters.moc" |