cppcodegen_test.cpp 19.4 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
Bill King's avatar
Bill King committed
2
**
hjk's avatar
hjk committed
3 4
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
Bill King's avatar
Bill King committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
Bill King's avatar
Bill King committed
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
Bill King's avatar
Bill King committed
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
Bill King's avatar
Bill King committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
Bill King's avatar
Bill King committed
29

30 31
#include "cpptoolsplugin.h"

32 33 34 35 36 37 38
#include <AST.h>
#include <Control.h>
#include <CppDocument.h>
#include <DiagnosticClient.h>
#include <Scope.h>
#include <TranslationUnit.h>
#include <Literals.h>
Roberto Raggi's avatar
Compile  
Roberto Raggi committed
39
#include <Bind.h>
40
#include <Symbols.h>
41 42
#include <cpptools/insertionpointlocator.h>
#include <cpptools/cpprefactoringchanges.h>
43 44
#include <cpptools/cpptoolsplugin.h>
#include <extensionsystem/pluginmanager.h>
45
#include <utils/fileutils.h>
46 47

#include <QtTest>
hjk's avatar
hjk committed
48
#include <QDebug>
49
#include <QTextDocument>
50
#include <QDir>
51

52 53 54 55
/*!
    Tests for various parts of the code generation. Well, okay, currently it only
    tests the InsertionPointLocator.
 */
56
using namespace CPlusPlus;
57
using namespace CppTools;
58
using namespace CppTools::Internal;
59

60 61 62
/*!
    Should insert at line 3, column 1, with "public:\n" as prefix and without suffix.
 */
63
void CppToolsPlugin::test_codegen_public_in_empty_class()
64 65 66 67
{
    const QByteArray src = "\n"
            "class Foo\n" // line 1
            "{\n"
68
            "};\n"
69 70
            "\n";

71
    Document::Ptr doc = Document::create("public_in_empty_class");
72
    doc->setUtf8Source(src);
73 74 75 76 77 78
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

79 80 81 82 83 84 85
    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);

    Snapshot snapshot;
    snapshot.insert(doc);
86
    CppRefactoringChanges changes(snapshot);
87
    InsertionPointLocator find(changes);
88
    InsertionLocation loc = find.methodDeclarationInClass(
89 90
                doc->fileName(),
                foo,
91
                InsertionPointLocator::Public);
92
    QVERIFY(loc.isValid());
93
    QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
94
    QVERIFY(loc.suffix().isEmpty());
95
    QCOMPARE(loc.line(), 3U);
96 97 98
    QCOMPARE(loc.column(), 1U);
}

99 100 101
/*!
    Should insert at line 3, column 1, without prefix and without suffix.
 */
102
void CppToolsPlugin::test_codegen_public_in_nonempty_class()
103 104 105 106
{
    const QByteArray src = "\n"
            "class Foo\n" // line 1
            "{\n"
107 108
            "public:\n"   // line 3
            "};\n"        // line 4
109 110
            "\n";

111
    Document::Ptr doc = Document::create("public_in_nonempty_class");
112
    doc->setUtf8Source(src);
113 114 115 116 117 118
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

119 120 121 122
    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
123

124 125
    Snapshot snapshot;
    snapshot.insert(doc);
126
    CppRefactoringChanges changes(snapshot);
127
    InsertionPointLocator find(changes);
128
    InsertionLocation loc = find.methodDeclarationInClass(
129 130
                doc->fileName(),
                foo,
131
                InsertionPointLocator::Public);
132
    QVERIFY(loc.isValid());
133
    QVERIFY(loc.prefix().isEmpty());
134
    QVERIFY(loc.suffix().isEmpty());
135
    QCOMPARE(loc.line(), 4U);
136 137 138
    QCOMPARE(loc.column(), 1U);
}

139 140 141
/*!
    Should insert at line 3, column 1, with "public:\n" as prefix and "\n suffix.
 */
142
void CppToolsPlugin::test_codegen_public_before_protected()
143 144 145 146 147 148 149 150 151
{
    const QByteArray src = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "protected:\n" // line 3
            "};\n"
            "\n";

    Document::Ptr doc = Document::create("public_before_protected");
152
    doc->setUtf8Source(src);
153 154 155 156 157 158
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

159 160 161 162
    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
163

164 165
    Snapshot snapshot;
    snapshot.insert(doc);
166
    CppRefactoringChanges changes(snapshot);
167
    InsertionPointLocator find(changes);
168
    InsertionLocation loc = find.methodDeclarationInClass(
169 170
                doc->fileName(),
                foo,
171
                InsertionPointLocator::Public);
172 173 174 175 176 177 178
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
    QCOMPARE(loc.suffix(), QLatin1String("\n"));
    QCOMPARE(loc.column(), 1U);
    QCOMPARE(loc.line(), 3U);
}

179 180 181 182
/*!
    Should insert at line 4, column 1, with "private:\n" as prefix and without
    suffix.
 */
183
void CppToolsPlugin::test_codegen_private_after_protected()
184 185 186 187 188 189 190 191 192
{
    const QByteArray src = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "protected:\n" // line 3
            "};\n"
            "\n";

    Document::Ptr doc = Document::create("private_after_protected");
193
    doc->setUtf8Source(src);
194 195 196 197 198 199
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

200 201 202 203
    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
204

205 206
    Snapshot snapshot;
    snapshot.insert(doc);
207
    CppRefactoringChanges changes(snapshot);
208
    InsertionPointLocator find(changes);
209
    InsertionLocation loc = find.methodDeclarationInClass(
210 211
                doc->fileName(),
                foo,
212
                InsertionPointLocator::Private);
213 214 215 216 217 218 219
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("private:\n"));
    QVERIFY(loc.suffix().isEmpty());
    QCOMPARE(loc.column(), 1U);
    QCOMPARE(loc.line(), 4U);
}

220 221 222 223
/*!
    Should insert at line 4, column 1, with "protected:\n" as prefix and without
    suffix.
 */
224
void CppToolsPlugin::test_codegen_protected_in_nonempty_class()
225 226 227 228 229 230 231 232 233
{
    const QByteArray src = "\n"
            "class Foo\n" // line 1
            "{\n"
            "public:\n"   // line 3
            "};\n"        // line 4
            "\n";

    Document::Ptr doc = Document::create("protected_in_nonempty_class");
234
    doc->setUtf8Source(src);
235 236 237 238 239 240
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

241 242 243 244
    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
245

246 247
    Snapshot snapshot;
    snapshot.insert(doc);
248
    CppRefactoringChanges changes(snapshot);
249
    InsertionPointLocator find(changes);
250
    InsertionLocation loc = find.methodDeclarationInClass(
251 252
                doc->fileName(),
                foo,
253
                InsertionPointLocator::Protected);
254 255 256 257 258 259 260
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("protected:\n"));
    QVERIFY(loc.suffix().isEmpty());
    QCOMPARE(loc.column(), 1U);
    QCOMPARE(loc.line(), 4U);
}

261 262 263
/*!
    Should insert at line 4, column 1, with "protected\n" as prefix and "\n" suffix.
 */
264
void CppToolsPlugin::test_codegen_protected_between_public_and_private()
265 266 267 268 269 270 271 272 273 274
{
    const QByteArray src = "\n"
            "class Foo\n" // line 1
            "{\n"
            "public:\n"   // line 3
            "private:\n"  // line 4
            "};\n"        // line 5
            "\n";

    Document::Ptr doc = Document::create("protected_betwee_public_and_private");
275
    doc->setUtf8Source(src);
276 277 278 279 280 281
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 1U);

282 283 284 285
    Class *foo = doc->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
286

287 288
    Snapshot snapshot;
    snapshot.insert(doc);
289
    CppRefactoringChanges changes(snapshot);
290
    InsertionPointLocator find(changes);
291
    InsertionLocation loc = find.methodDeclarationInClass(
292 293
                doc->fileName(),
                foo,
294
                InsertionPointLocator::Protected);
295 296 297 298 299 300 301
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("protected:\n"));
    QCOMPARE(loc.suffix(), QLatin1String("\n"));
    QCOMPARE(loc.column(), 1U);
    QCOMPARE(loc.line(), 4U);
}

302 303 304 305 306 307 308
/*!
    Should insert at line 18, column 1, with "private slots:\n" as prefix and "\n"
    as suffix.

    This is the typical Qt Designer case, with test-input like what the integration
    generates.
 */
309
void CppToolsPlugin::test_codegen_qtdesigner_integration()
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
{
    const QByteArray src = "/**** Some long (C)opyright notice ****/\n"
            "#ifndef MAINWINDOW_H\n"
            "#define MAINWINDOW_H\n"
            "\n"
            "#include <QMainWindow>\n"
            "\n"
            "namespace Ui {\n"
            "    class MainWindow;\n"
            "}\n"
            "\n"
            "class MainWindow : public QMainWindow\n" // line 10
            "{\n"
            "    Q_OBJECT\n"
            "\n"
            "public:\n" // line 14
            "    explicit MainWindow(QWidget *parent = 0);\n"
            "    ~MainWindow();\n"
            "\n"
            "private:\n" // line 18
            "    Ui::MainWindow *ui;\n"
            "};\n"
            "\n"
            "#endif // MAINWINDOW_H\n";

    Document::Ptr doc = Document::create("qtdesigner_integration");
336
    doc->setUtf8Source(src);
337 338 339 340 341 342
    doc->parse();
    doc->check();

    QCOMPARE(doc->diagnosticMessages().size(), 0);
    QCOMPARE(doc->globalSymbolCount(), 2U);

343 344 345 346
    Class *foo = doc->globalSymbolAt(1)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 10U);
    QCOMPARE(foo->column(), 7U);
347

348 349
    Snapshot snapshot;
    snapshot.insert(doc);
350
    CppRefactoringChanges changes(snapshot);
351
    InsertionPointLocator find(changes);
352
    InsertionLocation loc = find.methodDeclarationInClass(
353 354
                doc->fileName(),
                foo,
355
                InsertionPointLocator::PrivateSlot);
356 357 358 359 360 361 362
    QVERIFY(loc.isValid());
    QCOMPARE(loc.prefix(), QLatin1String("private slots:\n"));
    QCOMPARE(loc.suffix(), QLatin1String("\n"));
    QCOMPARE(loc.line(), 18U);
    QCOMPARE(loc.column(), 1U);
}

363
void CppToolsPlugin::test_codegen_definition_empty_class()
364 365 366 367 368 369 370 371 372 373 374 375
{
    const QByteArray srcText = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "void foo();\n" // line 3
            "};\n"
            "\n";

    const QByteArray dstText = "\n"
            "int x;\n"  // line 1
            "\n";

376
    Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
377 378 379
    Utils::FileSaver srcSaver(src->fileName());
    srcSaver.write(srcText);
    srcSaver.finalize();
380
    src->setUtf8Source(srcText);
381 382 383 384 385
    src->parse();
    src->check();
    QCOMPARE(src->diagnosticMessages().size(), 0);
    QCOMPARE(src->globalSymbolCount(), 1U);

386
    Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp"));
387 388 389
    Utils::FileSaver dstSaver(dst->fileName());
    dstSaver.write(dstText);
    dstSaver.finalize();
390
    dst->setUtf8Source(dstText);
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
    dst->parse();
    dst->check();
    QCOMPARE(dst->diagnosticMessages().size(), 0);
    QCOMPARE(dst->globalSymbolCount(), 1U);

    Snapshot snapshot;
    snapshot.insert(src);
    snapshot.insert(dst);

    Class *foo = src->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
    QCOMPARE(foo->memberCount(), 1U);
    Declaration *decl = foo->memberAt(0)->asDeclaration();
    QVERIFY(decl);
    QCOMPARE(decl->line(), 3U);
    QCOMPARE(decl->column(), 6U);

    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    QList<InsertionLocation> locList = find.methodDefinition(decl);
    QVERIFY(locList.size() == 1);
    InsertionLocation loc = locList.first();
415
    QCOMPARE(loc.fileName(), dst->fileName());
416 417
    QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
    QCOMPARE(loc.suffix(), QString());
Leandro Melo's avatar
Leandro Melo committed
418 419
    QCOMPARE(loc.line(), 3U);
    QCOMPARE(loc.column(), 1U);
420 421
}

422
void CppToolsPlugin::test_codegen_definition_first_member()
423 424 425 426 427 428 429 430 431
{
    const QByteArray srcText = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "void foo();\n" // line 3
            "void bar();\n" // line 4
            "};\n"
            "\n";

432 433 434 435 436 437 438 439 440 441
    const QByteArray dstText = QString(
                "\n"
                "#include \"%1/file.h\"\n" // line 1
                "int x;\n"
                "\n"
                "void Foo::bar()\n" // line 4
                "{\n"
                "\n"
                "}\n"
                "\n"
442
                "int y;\n").arg(QDir::tempPath()).toLatin1();
443

444
    Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
445 446 447
    Utils::FileSaver srcSaver(src->fileName());
    srcSaver.write(srcText);
    srcSaver.finalize();
448
    src->setUtf8Source(srcText);
449 450 451 452 453
    src->parse();
    src->check();
    QCOMPARE(src->diagnosticMessages().size(), 0);
    QCOMPARE(src->globalSymbolCount(), 1U);

454
    Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp"));
455
    dst->addIncludeFile(src->fileName(), 1);
456 457 458
    Utils::FileSaver dstSaver(dst->fileName());
    dstSaver.write(dstText);
    dstSaver.finalize();
459
    dst->setUtf8Source(dstText);
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
    dst->parse();
    dst->check();
    QCOMPARE(dst->diagnosticMessages().size(), 0);
    QCOMPARE(dst->globalSymbolCount(), 3U);

    Snapshot snapshot;
    snapshot.insert(src);
    snapshot.insert(dst);

    Class *foo = src->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
    QCOMPARE(foo->memberCount(), 2U);
    Declaration *decl = foo->memberAt(0)->asDeclaration();
    QVERIFY(decl);
    QCOMPARE(decl->line(), 3U);
    QCOMPARE(decl->column(), 6U);

    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    QList<InsertionLocation> locList = find.methodDefinition(decl);
    QVERIFY(locList.size() == 1);
    InsertionLocation loc = locList.first();
484
    QCOMPARE(loc.fileName(), dst->fileName());
485 486 487 488 489 490
    QCOMPARE(loc.line(), 4U);
    QCOMPARE(loc.column(), 1U);
    QCOMPARE(loc.suffix(), QLatin1String("\n\n"));
    QCOMPARE(loc.prefix(), QString());
}

491
void CppToolsPlugin::test_codegen_definition_last_member()
492 493 494 495 496 497 498 499 500
{
    const QByteArray srcText = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "void foo();\n" // line 3
            "void bar();\n" // line 4
            "};\n"
            "\n";

501 502 503 504 505 506 507 508 509 510
    const QByteArray dstText = QString(
                "\n"
                "#include \"%1/file.h\"\n" // line 1
                "int x;\n"
                "\n"
                "void Foo::foo()\n" // line 4
                "{\n"
                "\n"
                "}\n" // line 7
                "\n"
511
                "int y;\n").arg(QDir::tempPath()).toLatin1();
512

513
    Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
514 515 516
    Utils::FileSaver srcSaver(src->fileName());
    srcSaver.write(srcText);
    srcSaver.finalize();
517
    src->setUtf8Source(srcText);
518 519 520 521 522
    src->parse();
    src->check();
    QCOMPARE(src->diagnosticMessages().size(), 0);
    QCOMPARE(src->globalSymbolCount(), 1U);

523
    Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp"));
524
    dst->addIncludeFile(src->fileName(), 1);
525 526 527
    Utils::FileSaver dstSaver(dst->fileName());
    dstSaver.write(dstText);
    dstSaver.finalize();
528
    dst->setUtf8Source(dstText);
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
    dst->parse();
    dst->check();
    QCOMPARE(dst->diagnosticMessages().size(), 0);
    QCOMPARE(dst->globalSymbolCount(), 3U);

    Snapshot snapshot;
    snapshot.insert(src);
    snapshot.insert(dst);

    Class *foo = src->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
    QCOMPARE(foo->memberCount(), 2U);
    Declaration *decl = foo->memberAt(1)->asDeclaration();
    QVERIFY(decl);
    QCOMPARE(decl->line(), 4U);
    QCOMPARE(decl->column(), 6U);

    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    QList<InsertionLocation> locList = find.methodDefinition(decl);
    QVERIFY(locList.size() == 1);
    InsertionLocation loc = locList.first();
553
    QCOMPARE(loc.fileName(), dst->fileName());
554 555 556 557 558 559
    QCOMPARE(loc.line(), 7U);
    QCOMPARE(loc.column(), 2U);
    QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
    QCOMPARE(loc.suffix(), QString());
}

560
void CppToolsPlugin::test_codegen_definition_middle_member()
561 562 563 564 565 566 567 568 569 570
{
    const QByteArray srcText = "\n"
            "class Foo\n"  // line 1
            "{\n"
            "void foo();\n" // line 3
            "void bar();\n" // line 4
            "void car();\n" // line 5
            "};\n"
            "\n";

571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
    const QByteArray dstText = QString(
                "\n"
                "#include \"%1/file.h\"\n" // line 1
                "int x;\n"
                "\n"
                "void Foo::foo()\n" // line 4
                "{\n"
                "\n"
                "}\n" // line 7
                "\n"
                "void Foo::car()\n" // line 9
                "{\n"
                "\n"
                "}\n"
                "\n"
586
                "int y;\n").arg(QDir::tempPath()).toLatin1();
587

588
    Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h"));
589 590 591
    Utils::FileSaver srcSaver(src->fileName());
    srcSaver.write(srcText);
    srcSaver.finalize();
592
    src->setUtf8Source(srcText);
593 594 595 596 597
    src->parse();
    src->check();
    QCOMPARE(src->diagnosticMessages().size(), 0);
    QCOMPARE(src->globalSymbolCount(), 1U);

598
    Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp"));
599
    dst->addIncludeFile(src->fileName(), 1);
600 601 602
    Utils::FileSaver dstSaver(dst->fileName());
    dstSaver.write(dstText);
    dstSaver.finalize();
603
    dst->setUtf8Source(dstText);
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
    dst->parse();
    dst->check();
    QCOMPARE(dst->diagnosticMessages().size(), 0);
    QCOMPARE(dst->globalSymbolCount(), 4U);

    Snapshot snapshot;
    snapshot.insert(src);
    snapshot.insert(dst);

    Class *foo = src->globalSymbolAt(0)->asClass();
    QVERIFY(foo);
    QCOMPARE(foo->line(), 1U);
    QCOMPARE(foo->column(), 7U);
    QCOMPARE(foo->memberCount(), 3U);
    Declaration *decl = foo->memberAt(1)->asDeclaration();
    QVERIFY(decl);
    QCOMPARE(decl->line(), 4U);
    QCOMPARE(decl->column(), 6U);

    CppRefactoringChanges changes(snapshot);
    InsertionPointLocator find(changes);
    QList<InsertionLocation> locList = find.methodDefinition(decl);
    QVERIFY(locList.size() == 1);
    InsertionLocation loc = locList.first();
628
    QCOMPARE(loc.fileName(), dst->fileName());
629 630 631 632 633
    QCOMPARE(loc.line(), 7U);
    QCOMPARE(loc.column(), 2U);
    QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
    QCOMPARE(loc.suffix(), QString());
}