OSDN Git Service

c36d94ec5c74381286d6faa665fcaae718aef74c
[qt-creator-jp/qt-creator-jp.git] / tests / auto / cplusplus / codegen / tst_codegen.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include <AST.h>
35 #include <Control.h>
36 #include <CppDocument.h>
37 #include <DiagnosticClient.h>
38 #include <Scope.h>
39 #include <TranslationUnit.h>
40 #include <Literals.h>
41 #include <Bind.h>
42 #include <Symbols.h>
43 #include <cpptools/insertionpointlocator.h>
44 #include <cpptools/cpprefactoringchanges.h>
45 #include <cpptools/cpptoolsplugin.h>
46 #include <extensionsystem/pluginmanager.h>
47
48 #include <QtTest>
49 #include <QtDebug>
50 #include <QTextDocument>
51
52 //TESTED_COMPONENT=src/libs/cplusplus
53
54 /*!
55     Tests for various parts of the code generation. Well, okay, currently it only
56     tests the InsertionPointLocator.
57  */
58 using namespace CPlusPlus;
59 using namespace CppTools;
60
61 class tst_Codegen: public QObject
62 {
63     Q_OBJECT
64
65 private slots:
66     void initTestCase();
67     void cleanupTestCase();
68     void public_in_empty_class();
69     void public_in_nonempty_class();
70     void public_before_protected();
71     void private_after_protected();
72     void protected_in_nonempty_class();
73     void protected_betwee_public_and_private();
74     void qtdesigner_integration();
75 private:
76     ExtensionSystem::PluginManager *pluginManager;
77 };
78
79 void tst_Codegen::initTestCase()
80 {
81     pluginManager = new ExtensionSystem::PluginManager;
82     QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
83                                  QLatin1String("Nokia"), QLatin1String("QtCreator"));
84     pluginManager->setSettings(settings);
85     pluginManager->setFileExtension(QLatin1String("pluginspec"));
86     pluginManager->setPluginPaths(QStringList() << QLatin1String(Q_PLUGIN_PATH));
87     pluginManager->loadPlugins();
88 }
89
90 void tst_Codegen::cleanupTestCase()
91 {
92     pluginManager->shutdown();
93     delete pluginManager;
94 }
95 /*!
96     Should insert at line 3, column 1, with "public:\n" as prefix and without suffix.
97  */
98 void tst_Codegen::public_in_empty_class()
99 {
100     const QByteArray src = "\n"
101             "class Foo\n" // line 1
102             "{\n"
103             "};\n"
104             "\n";
105
106     Document::Ptr doc = Document::create("public_in_empty_class");
107     doc->setSource(src);
108     doc->parse();
109     doc->check();
110
111     QCOMPARE(doc->diagnosticMessages().size(), 0);
112     QCOMPARE(doc->globalSymbolCount(), 1U);
113
114     Class *foo = doc->globalSymbolAt(0)->asClass();
115     QVERIFY(foo);
116     QCOMPARE(foo->line(), 1U);
117     QCOMPARE(foo->column(), 7U);
118
119     Snapshot snapshot;
120     snapshot.insert(doc);
121     CppRefactoringChanges changes(snapshot);
122     InsertionPointLocator find(&changes);
123     InsertionLocation loc = find.methodDeclarationInClass(
124                 doc->fileName(),
125                 foo,
126                 InsertionPointLocator::Public);
127     QVERIFY(loc.isValid());
128     QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
129     QVERIFY(loc.suffix().isEmpty());
130     QCOMPARE(loc.line(), 3U);
131     QCOMPARE(loc.column(), 1U);
132 }
133
134 /*!
135     Should insert at line 3, column 1, without prefix and without suffix.
136  */
137 void tst_Codegen::public_in_nonempty_class()
138 {
139     const QByteArray src = "\n"
140             "class Foo\n" // line 1
141             "{\n"
142             "public:\n"   // line 3
143             "};\n"        // line 4
144             "\n";
145
146     Document::Ptr doc = Document::create("public_in_nonempty_class");
147     doc->setSource(src);
148     doc->parse();
149     doc->check();
150
151     QCOMPARE(doc->diagnosticMessages().size(), 0);
152     QCOMPARE(doc->globalSymbolCount(), 1U);
153
154     Class *foo = doc->globalSymbolAt(0)->asClass();
155     QVERIFY(foo);
156     QCOMPARE(foo->line(), 1U);
157     QCOMPARE(foo->column(), 7U);
158
159     Snapshot snapshot;
160     snapshot.insert(doc);
161     CppRefactoringChanges changes(snapshot);
162     InsertionPointLocator find(&changes);
163     InsertionLocation loc = find.methodDeclarationInClass(
164                 doc->fileName(),
165                 foo,
166                 InsertionPointLocator::Public);
167     QVERIFY(loc.isValid());
168     QVERIFY(loc.prefix().isEmpty());
169     QVERIFY(loc.suffix().isEmpty());
170     QCOMPARE(loc.line(), 4U);
171     QCOMPARE(loc.column(), 1U);
172 }
173
174 /*!
175     Should insert at line 3, column 1, with "public:\n" as prefix and "\n suffix.
176  */
177 void tst_Codegen::public_before_protected()
178 {
179     const QByteArray src = "\n"
180             "class Foo\n"  // line 1
181             "{\n"
182             "protected:\n" // line 3
183             "};\n"
184             "\n";
185
186     Document::Ptr doc = Document::create("public_before_protected");
187     doc->setSource(src);
188     doc->parse();
189     doc->check();
190
191     QCOMPARE(doc->diagnosticMessages().size(), 0);
192     QCOMPARE(doc->globalSymbolCount(), 1U);
193
194     Class *foo = doc->globalSymbolAt(0)->asClass();
195     QVERIFY(foo);
196     QCOMPARE(foo->line(), 1U);
197     QCOMPARE(foo->column(), 7U);
198
199     Snapshot snapshot;
200     snapshot.insert(doc);
201     CppRefactoringChanges changes(snapshot);
202     InsertionPointLocator find(&changes);
203     InsertionLocation loc = find.methodDeclarationInClass(
204                 doc->fileName(),
205                 foo,
206                 InsertionPointLocator::Public);
207     QVERIFY(loc.isValid());
208     QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
209     QCOMPARE(loc.suffix(), QLatin1String("\n"));
210     QCOMPARE(loc.column(), 1U);
211     QCOMPARE(loc.line(), 3U);
212 }
213
214 /*!
215     Should insert at line 4, column 1, with "private:\n" as prefix and without
216     suffix.
217  */
218 void tst_Codegen::private_after_protected()
219 {
220     const QByteArray src = "\n"
221             "class Foo\n"  // line 1
222             "{\n"
223             "protected:\n" // line 3
224             "};\n"
225             "\n";
226
227     Document::Ptr doc = Document::create("private_after_protected");
228     doc->setSource(src);
229     doc->parse();
230     doc->check();
231
232     QCOMPARE(doc->diagnosticMessages().size(), 0);
233     QCOMPARE(doc->globalSymbolCount(), 1U);
234
235     Class *foo = doc->globalSymbolAt(0)->asClass();
236     QVERIFY(foo);
237     QCOMPARE(foo->line(), 1U);
238     QCOMPARE(foo->column(), 7U);
239
240     Snapshot snapshot;
241     snapshot.insert(doc);
242     CppRefactoringChanges changes(snapshot);
243     InsertionPointLocator find(&changes);
244     InsertionLocation loc = find.methodDeclarationInClass(
245                 doc->fileName(),
246                 foo,
247                 InsertionPointLocator::Private);
248     QVERIFY(loc.isValid());
249     QCOMPARE(loc.prefix(), QLatin1String("private:\n"));
250     QVERIFY(loc.suffix().isEmpty());
251     QCOMPARE(loc.column(), 1U);
252     QCOMPARE(loc.line(), 4U);
253 }
254
255 /*!
256     Should insert at line 4, column 1, with "protected:\n" as prefix and without
257     suffix.
258  */
259 void tst_Codegen::protected_in_nonempty_class()
260 {
261     const QByteArray src = "\n"
262             "class Foo\n" // line 1
263             "{\n"
264             "public:\n"   // line 3
265             "};\n"        // line 4
266             "\n";
267
268     Document::Ptr doc = Document::create("protected_in_nonempty_class");
269     doc->setSource(src);
270     doc->parse();
271     doc->check();
272
273     QCOMPARE(doc->diagnosticMessages().size(), 0);
274     QCOMPARE(doc->globalSymbolCount(), 1U);
275
276     Class *foo = doc->globalSymbolAt(0)->asClass();
277     QVERIFY(foo);
278     QCOMPARE(foo->line(), 1U);
279     QCOMPARE(foo->column(), 7U);
280
281     Snapshot snapshot;
282     snapshot.insert(doc);
283     CppRefactoringChanges changes(snapshot);
284     InsertionPointLocator find(&changes);
285     InsertionLocation loc = find.methodDeclarationInClass(
286                 doc->fileName(),
287                 foo,
288                 InsertionPointLocator::Protected);
289     QVERIFY(loc.isValid());
290     QCOMPARE(loc.prefix(), QLatin1String("protected:\n"));
291     QVERIFY(loc.suffix().isEmpty());
292     QCOMPARE(loc.column(), 1U);
293     QCOMPARE(loc.line(), 4U);
294 }
295
296 /*!
297     Should insert at line 4, column 1, with "protected\n" as prefix and "\n" suffix.
298  */
299 void tst_Codegen::protected_betwee_public_and_private()
300 {
301     const QByteArray src = "\n"
302             "class Foo\n" // line 1
303             "{\n"
304             "public:\n"   // line 3
305             "private:\n"  // line 4
306             "};\n"        // line 5
307             "\n";
308
309     Document::Ptr doc = Document::create("protected_betwee_public_and_private");
310     doc->setSource(src);
311     doc->parse();
312     doc->check();
313
314     QCOMPARE(doc->diagnosticMessages().size(), 0);
315     QCOMPARE(doc->globalSymbolCount(), 1U);
316
317     Class *foo = doc->globalSymbolAt(0)->asClass();
318     QVERIFY(foo);
319     QCOMPARE(foo->line(), 1U);
320     QCOMPARE(foo->column(), 7U);
321
322     Snapshot snapshot;
323     snapshot.insert(doc);
324     CppRefactoringChanges changes(snapshot);
325     InsertionPointLocator find(&changes);
326     InsertionLocation loc = find.methodDeclarationInClass(
327                 doc->fileName(),
328                 foo,
329                 InsertionPointLocator::Protected);
330     QVERIFY(loc.isValid());
331     QCOMPARE(loc.prefix(), QLatin1String("protected:\n"));
332     QCOMPARE(loc.suffix(), QLatin1String("\n"));
333     QCOMPARE(loc.column(), 1U);
334     QCOMPARE(loc.line(), 4U);
335 }
336
337 /*!
338     Should insert at line 18, column 1, with "private slots:\n" as prefix and "\n"
339     as suffix.
340
341     This is the typical Qt Designer case, with test-input like what the integration
342     generates.
343  */
344 void tst_Codegen::qtdesigner_integration()
345 {
346     const QByteArray src = "/**** Some long (C)opyright notice ****/\n"
347             "#ifndef MAINWINDOW_H\n"
348             "#define MAINWINDOW_H\n"
349             "\n"
350             "#include <QMainWindow>\n"
351             "\n"
352             "namespace Ui {\n"
353             "    class MainWindow;\n"
354             "}\n"
355             "\n"
356             "class MainWindow : public QMainWindow\n" // line 10
357             "{\n"
358             "    Q_OBJECT\n"
359             "\n"
360             "public:\n" // line 14
361             "    explicit MainWindow(QWidget *parent = 0);\n"
362             "    ~MainWindow();\n"
363             "\n"
364             "private:\n" // line 18
365             "    Ui::MainWindow *ui;\n"
366             "};\n"
367             "\n"
368             "#endif // MAINWINDOW_H\n";
369
370     Document::Ptr doc = Document::create("qtdesigner_integration");
371     doc->setSource(src);
372     doc->parse();
373     doc->check();
374
375     QCOMPARE(doc->diagnosticMessages().size(), 0);
376     QCOMPARE(doc->globalSymbolCount(), 2U);
377
378     Class *foo = doc->globalSymbolAt(1)->asClass();
379     QVERIFY(foo);
380     QCOMPARE(foo->line(), 10U);
381     QCOMPARE(foo->column(), 7U);
382
383     Snapshot snapshot;
384     snapshot.insert(doc);
385     CppRefactoringChanges changes(snapshot);
386     InsertionPointLocator find(&changes);
387     InsertionLocation loc = find.methodDeclarationInClass(
388                 doc->fileName(),
389                 foo,
390                 InsertionPointLocator::PrivateSlot);
391     QVERIFY(loc.isValid());
392     QCOMPARE(loc.prefix(), QLatin1String("private slots:\n"));
393     QCOMPARE(loc.suffix(), QLatin1String("\n"));
394     QCOMPARE(loc.line(), 18U);
395     QCOMPARE(loc.column(), 1U);
396 }
397
398 QTEST_MAIN(tst_Codegen)
399 #include "tst_codegen.moc"