81a51e10f38464d2325137518fbcccb564346dd6
[profile/ivi/qtbase.git] / tests / auto / qmake / tst_qmake.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
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 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43
44 #if !defined(QMAKE_CROSS_COMPILED)
45
46 #include "testcompiler.h"
47
48 #include <QObject>
49 #include <QDir>
50
51 class tst_qmake : public QObject
52 {
53     Q_OBJECT
54
55 public:
56     tst_qmake();
57     virtual ~tst_qmake();
58
59 public slots:
60     void initTestCase();
61     void cleanupTestCase();
62     void init();
63     void cleanup();
64
65 private slots:
66     void simple_app();
67     void simple_app_shadowbuild();
68     void simple_app_shadowbuild2();
69     void simple_lib();
70     void simple_dll();
71     void subdirs();
72     void functions();
73     void operators();
74     void variables();
75     void func_export();
76     void func_variables();
77     void comments();
78     void duplicateLibraryEntries();
79     void export_across_file_boundaries();
80     void include_dir();
81     void install_files();
82     void install_depends();
83     void quotedfilenames();
84     void prompt();
85     void one_space();
86     void findMocs();
87     void findDeps();
88 #ifndef Q_OS_WIN
89     // Test requires make
90     void bundle_spaces();
91 #endif
92     void includefunction();
93     void substitutes();
94
95 private:
96     TestCompiler test_compiler;
97     QString base_path;
98 };
99
100 tst_qmake::tst_qmake()
101 {
102     QString binpath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
103     QString cmd = QString("%2/qmake \"QT_VERSION=%1\"").arg(QT_VERSION).arg(binpath);
104 #ifdef Q_CC_MSVC
105     test_compiler.setBaseCommands( "nmake", cmd );
106 #elif defined(Q_CC_MINGW)
107     test_compiler.setBaseCommands( "mingw32-make", cmd );
108 #elif defined(Q_OS_WIN) && defined(Q_CC_GNU)
109     test_compiler.setBaseCommands( "mmmake", cmd );
110 #else
111     test_compiler.setBaseCommands( "make", cmd );
112 #endif
113     QDir dir;
114     base_path = dir.currentPath();
115 }
116
117 tst_qmake::~tst_qmake()
118 {
119
120 }
121
122 void tst_qmake::initTestCase()
123 {
124 }
125
126 void tst_qmake::cleanupTestCase()
127 {
128 }
129
130 void tst_qmake::init()
131 {
132     test_compiler.clearCommandOutput();
133 }
134
135 void tst_qmake::cleanup()
136 {
137     test_compiler.clearCommandOutput();
138 }
139
140 void tst_qmake::simple_app()
141 {
142     QString workDir = base_path + "/testdata/simple_app";
143
144     QVERIFY( test_compiler.qmake( workDir, "simple_app" ));
145     QVERIFY( test_compiler.make( workDir ));
146     QVERIFY( test_compiler.exists( workDir, "simple_app", Exe, "1.0.0" ));
147     QVERIFY( test_compiler.makeClean( workDir ));
148     QVERIFY( test_compiler.exists( workDir, "simple_app", Exe, "1.0.0" )); // Should still exist after a make clean
149     QVERIFY( test_compiler.makeDistClean( workDir ));
150     QVERIFY( !test_compiler.exists( workDir, "simple_app", Exe, "1.0.0" )); // Should not exist after a make distclean
151     QVERIFY( test_compiler.removeMakefile( workDir ) );
152 }
153
154 void tst_qmake::simple_app_shadowbuild()
155 {
156     QString workDir = base_path + "/testdata/simple_app";
157     QString buildDir = base_path + "/testdata/simple_app_build";
158
159     QVERIFY( test_compiler.qmake( workDir, "simple_app", buildDir ));
160     QVERIFY( test_compiler.make( buildDir ));
161     QVERIFY( test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" ));
162     QVERIFY( test_compiler.makeClean( buildDir ));
163     QVERIFY( test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); // Should still exist after a make clean
164     QVERIFY( test_compiler.makeDistClean( buildDir ));
165     QVERIFY( !test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); // Should not exist after a make distclean
166     QVERIFY( test_compiler.removeMakefile( buildDir ) );
167 }
168
169 void tst_qmake::simple_app_shadowbuild2()
170 {
171     QString workDir = base_path + "/testdata/simple_app";
172     QString buildDir = base_path + "/testdata/simple_app/build";
173
174     QVERIFY( test_compiler.qmake( workDir, "simple_app", buildDir ));
175     QVERIFY( test_compiler.make( buildDir ));
176     QVERIFY( test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" ));
177     QVERIFY( test_compiler.makeClean( buildDir ));
178     QVERIFY( test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); // Should still exist after a make clean
179     QVERIFY( test_compiler.makeDistClean( buildDir ));
180     QVERIFY( !test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); // Should not exist after a make distclean
181     QVERIFY( test_compiler.removeMakefile( buildDir ) );
182 }
183
184 void tst_qmake::simple_dll()
185 {
186     QString workDir = base_path + "/testdata/simple_dll";
187
188     QDir D;
189     D.remove( workDir + "/Makefile");
190     QVERIFY( test_compiler.qmake( workDir, "simple_dll" ));
191     QVERIFY( test_compiler.make( workDir ));
192     QVERIFY( test_compiler.exists( workDir, "simple_dll", Dll, "1.0.0" ));
193     QVERIFY( test_compiler.makeClean( workDir ));
194     QVERIFY( test_compiler.exists( workDir, "simple_dll", Dll, "1.0.0" )); // Should still exist after a make clean
195     QVERIFY( test_compiler.makeDistClean( workDir ));
196     QVERIFY( !test_compiler.exists( workDir, "simple_dll", Dll, "1.0.0" )); // Should not exist after a make distclean
197     QVERIFY( test_compiler.removeMakefile( workDir ) );
198 }
199
200 void tst_qmake::simple_lib()
201 {
202     QString workDir = base_path + "/testdata/simple_lib";
203
204     QDir D;
205     D.remove( workDir + "/Makefile");
206     QVERIFY( test_compiler.qmake( workDir, "simple_lib" ));
207     QVERIFY( test_compiler.make( workDir ));
208     QVERIFY( test_compiler.exists( workDir, "simple_lib", Lib, "1.0.0" ));
209     QVERIFY( test_compiler.makeClean( workDir ));
210     QVERIFY( test_compiler.exists( workDir, "simple_lib", Lib, "1.0.0" )); // Should still exist after a make clean
211     QVERIFY( test_compiler.makeDistClean( workDir ));
212     QVERIFY( !test_compiler.exists( workDir, "simple_lib", Lib, "1.0.0" )); // Should not exist after a make distclean
213     QVERIFY( test_compiler.removeMakefile( workDir ) );
214 }
215
216 void tst_qmake::subdirs()
217 {
218     QString workDir = base_path + "/testdata/subdirs";
219
220     QDir D;
221     D.remove( workDir + "/simple_app/Makefile");
222     D.remove( workDir + "/simple_dll/Makefile");
223     QVERIFY( test_compiler.qmake( workDir, "subdirs" ));
224     QVERIFY( test_compiler.make( workDir ));
225     QVERIFY( test_compiler.exists( workDir + "/simple_app", "simple_app", Exe, "1.0.0" ));
226     QVERIFY( test_compiler.exists( workDir + "/simple_dll", "simple_dll", Dll, "1.0.0" ));
227     QVERIFY( test_compiler.makeClean( workDir ));
228     // Should still exist after a make clean
229     QVERIFY( test_compiler.exists( workDir + "/simple_app", "simple_app", Exe, "1.0.0" ));
230     QVERIFY( test_compiler.exists( workDir + "/simple_dll", "simple_dll", Dll, "1.0.0" ));
231     // Since subdirs templates do not have a make dist clean, we should clean up ourselves
232     // properly
233     QVERIFY( test_compiler.makeDistClean( workDir ));
234     QVERIFY( test_compiler.removeMakefile( workDir ) );
235 }
236
237 void tst_qmake::functions()
238 {
239     QString workDir = base_path + "/testdata/functions";
240     QVERIFY( test_compiler.qmake( workDir, "functions" ));
241 }
242
243 void tst_qmake::operators()
244 {
245     QString workDir = base_path + "/testdata/operators";
246     QVERIFY( test_compiler.qmake( workDir, "operators" ));
247 }
248
249 void tst_qmake::variables()
250 {
251     QString workDir = base_path + "/testdata/variables";
252     QVERIFY(test_compiler.qmake( workDir, "variables" ));
253 }
254
255 void tst_qmake::func_export()
256 {
257     QString workDir = base_path + "/testdata/func_export";
258     QVERIFY(test_compiler.qmake( workDir, "func_export" ));
259 }
260
261 void tst_qmake::func_variables()
262 {
263     QString workDir = base_path + "/testdata/func_variables";
264     QVERIFY(test_compiler.qmake( workDir, "func_variables" ));
265 }
266
267 void tst_qmake::comments()
268 {
269     QString workDir = base_path + "/testdata/comments";
270     QVERIFY(test_compiler.qmake( workDir, "comments" ));
271 }
272
273 void tst_qmake::duplicateLibraryEntries()
274 {
275     QVERIFY(true);
276     /* TODO: this test does not work as the problem it tests doesn't happen
277     until after the parsing of the pro-file and thus has to be tested
278     by parsing the Makefile. This is not doable with the current
279     testcompiler framework and has as such been put on hold.
280
281     QString workDir = base_path + "/testdata/duplicateLibraryEntries";
282     QVERIFY(test_compiler.qmake(workDir, "duplicateLibraryEntries")); */
283 }
284
285 void tst_qmake::export_across_file_boundaries()
286 {
287     // This relies on features so we need to set the QMAKEFEATURES environment variable
288     test_compiler.addToEnvironment("QMAKEFEATURES=.");
289     QString workDir = base_path + "/testdata/export_across_file_boundaries";
290     QVERIFY( test_compiler.qmake( workDir, "foo" ));
291     test_compiler.resetEnvironment();
292 }
293
294 void tst_qmake::include_dir()
295 {
296     QString workDir = base_path + "/testdata/include_dir";
297     QVERIFY( test_compiler.qmake( workDir, "foo" ));
298     QVERIFY( test_compiler.make( workDir ));
299     QVERIFY( test_compiler.exists( workDir, "foo", Exe, "1.0.0" ));
300     QVERIFY( test_compiler.makeDistClean( workDir ));
301
302     QString buildDir = base_path + "/testdata/include_dir_build";
303     QVERIFY( test_compiler.qmake( workDir, "foo", buildDir ));
304     QVERIFY( test_compiler.make( buildDir ));
305     QVERIFY( test_compiler.exists( buildDir, "foo", Exe, "1.0.0" ));
306     QVERIFY( test_compiler.makeDistClean( buildDir ));
307 }
308
309 void tst_qmake::install_files()
310 {
311     QString workDir = base_path + "/testdata/shadow_files";
312     QVERIFY( test_compiler.qmake( workDir, "foo" ));
313     QVERIFY( test_compiler.make( workDir ));
314     QVERIFY( test_compiler.exists( workDir, "foo", Exe, "1.0.0" ));
315     QVERIFY( test_compiler.make( workDir, "install" ));
316     QVERIFY( test_compiler.exists( workDir + "/dist", "foo", Exe, "1.0.0" ));
317     QVERIFY( test_compiler.exists( workDir + "/dist", "test.txt", Plain, "1.0.0" ));
318     QVERIFY( test_compiler.make( workDir, "uninstall" ));
319     QVERIFY( test_compiler.makeDistClean( workDir ));
320
321     QString buildDir = base_path + "/testdata/shadow_files_build";
322     QVERIFY( test_compiler.qmake( workDir, "foo", buildDir ));
323     QVERIFY( test_compiler.make( buildDir ));
324     QVERIFY( test_compiler.exists( buildDir, "foo", Exe, "1.0.0" ));
325     QVERIFY( test_compiler.make( buildDir, "install" ));
326     QVERIFY( test_compiler.exists( workDir + "/dist", "foo", Exe, "1.0.0" ));
327     QVERIFY( test_compiler.exists( workDir + "/dist", "test.txt", Plain, "1.0.0" ));
328     QVERIFY( test_compiler.exists( workDir + "/dist", "foo.bar", Plain, "1.0.0" ));
329     QVERIFY( test_compiler.make( buildDir, "uninstall" ));
330     QVERIFY( test_compiler.makeDistClean( buildDir ));
331 }
332
333 void tst_qmake::install_depends()
334 {
335     QString workDir = base_path + "/testdata/install_depends";
336     QVERIFY( test_compiler.qmake( workDir, "foo" ));
337     QVERIFY( test_compiler.make( workDir ));
338     QVERIFY( test_compiler.exists( workDir, "foo", Exe, "1.0.0" ));
339     QVERIFY( test_compiler.make( workDir, "install" ));
340     QVERIFY( test_compiler.exists( workDir + "/dist", "foo", Exe, "1.0.0" ));
341     QVERIFY( test_compiler.exists( workDir + "/dist", "test1", Plain, "1.0.0" ));
342     QVERIFY( test_compiler.exists( workDir + "/dist", "test2", Plain, "1.0.0" ));
343     QVERIFY( test_compiler.make( workDir, "uninstall" ));
344     QVERIFY( test_compiler.makeDistClean( workDir ));
345 }
346 void tst_qmake::quotedfilenames()
347 {
348     QString workDir = base_path + "/testdata/quotedfilenames";
349     QVERIFY( test_compiler.qmake( workDir, "quotedfilenames" ));
350     QVERIFY( test_compiler.makeClean( workDir ));
351     QVERIFY( test_compiler.make( workDir ));
352     QVERIFY( test_compiler.exists( workDir, "quotedfilenames", Exe, "1.0.0" ));
353 }
354
355 void tst_qmake::prompt()
356 {
357 #if 0
358     QProcess qmake;
359     qmake.setReadChannelMode(QProcess::MergedChannels);
360     qmake.setWorkingDirectory(QLatin1String("testdata/prompt"));
361     qmake.start(QLatin1String("qmake CONFIG-=debug_and_release CONFIG-=debug CONFIG+=release"),
362                 QIODevice::Text | QIODevice::ReadWrite);
363     QVERIFY(qmake.waitForStarted(20000));
364     QByteArray read = qmake.readAll();
365     qDebug() << read;
366     QCOMPARE(read, QByteArray("Project PROMPT: Prompteroo? "));
367     qmake.write("promptetiprompt\n");
368     QVERIFY(qmake.waitForFinished(20000));
369 #endif
370 }
371
372 void tst_qmake::one_space()
373 {
374     QString workDir = base_path + "/testdata/one_space";
375
376     QVERIFY( test_compiler.qmake( workDir, "one_space" ));
377     QVERIFY( test_compiler.make( workDir ));
378     QVERIFY( test_compiler.exists( workDir, "one space", Exe, "1.0.0" ));
379     QVERIFY( test_compiler.makeClean( workDir ));
380     QVERIFY( test_compiler.exists( workDir, "one space", Exe, "1.0.0" )); // Should still exist after a make clean
381     QVERIFY( test_compiler.makeDistClean( workDir ));
382     QVERIFY( !test_compiler.exists( workDir, "one space", Exe, "1.0.0" )); // Should not exist after a make distclean
383     QVERIFY( test_compiler.removeMakefile( workDir ) );
384 }
385
386 void tst_qmake::findMocs()
387 {
388     QString workDir = base_path + "/testdata/findMocs";
389
390     QVERIFY( test_compiler.qmake(workDir, "findMocs") );
391     QVERIFY( test_compiler.make(workDir) );
392     QVERIFY( test_compiler.exists(workDir, "findMocs", Exe, "1.0.0" ) );
393     QVERIFY( test_compiler.makeClean(workDir) );
394     QVERIFY( test_compiler.exists(workDir, "findMocs", Exe, "1.0.0" ) );
395     QVERIFY( test_compiler.makeDistClean(workDir ) );
396     QVERIFY( !test_compiler.exists(workDir, "findMocs", Exe, "1.0.0" ) );
397     QVERIFY( test_compiler.removeMakefile(workDir) );
398 }
399
400 void tst_qmake::findDeps()
401 {
402     QString workDir = base_path + "/testdata/findDeps";
403
404     QVERIFY( test_compiler.qmake(workDir, "findDeps") );
405     QVERIFY( test_compiler.make(workDir) );
406     QVERIFY( test_compiler.exists(workDir, "findDeps", Exe, "1.0.0" ) );
407     QVERIFY( test_compiler.makeClean(workDir) );
408     QVERIFY( test_compiler.exists(workDir, "findDeps", Exe, "1.0.0" ) );
409     QVERIFY( test_compiler.makeDistClean(workDir ) );
410     QVERIFY( !test_compiler.exists(workDir, "findDeps", Exe, "1.0.0" ) );
411     QVERIFY( test_compiler.removeMakefile(workDir) );
412 }
413
414 struct TempFile
415     : QFile
416 {
417     TempFile(QString filename)
418         : QFile(filename)
419     {
420     }
421
422     ~TempFile()
423     {
424         if (this->exists())
425             this->remove();
426     }
427 };
428
429 #ifndef Q_OS_WIN
430 void tst_qmake::bundle_spaces()
431 {
432     QString workDir = base_path + "/testdata/bundle-spaces";
433
434     // We set up alternate commands here, to make sure we're testing Mac
435     // Bundles and since this might be the wrong output we rely on dry-running
436     // make (-n).
437
438     TestCompiler local_tc;
439     local_tc.setBaseCommands("make -n", "qmake -macx -spec macx-g++");
440
441     QVERIFY( local_tc.qmake(workDir, "bundle-spaces") );
442
443     TempFile non_existing_file(workDir + "/non-existing file");
444     QVERIFY( !non_existing_file.exists() );
445
446     // Make fails: no rule to make "non-existing file"
447     QVERIFY( !local_tc.make(workDir) );
448
449     QVERIFY( non_existing_file.open(QIODevice::WriteOnly) );
450     QVERIFY( non_existing_file.exists() );
451
452     // Aha!
453     QVERIFY( local_tc.make(workDir) );
454
455     // Cleanup
456     QVERIFY( non_existing_file.remove() );
457     QVERIFY( !non_existing_file.exists() );
458     QVERIFY( local_tc.removeMakefile(workDir) );
459 }
460 #endif // Q_OS_WIN
461
462 void tst_qmake::includefunction()
463 {
464     QString workDir = base_path + "/testdata/include_function";
465     QString warningMsg("Unable to find file for inclusion");
466     QVERIFY(test_compiler.qmake( workDir, "include_existing_file"));
467     QVERIFY(!test_compiler.commandOutput().contains(warningMsg));
468
469     // test include()  usage on a missing file
470     test_compiler.clearCommandOutput();
471     workDir = base_path + "/testdata/include_function";
472     QVERIFY(test_compiler.qmake( workDir, "include_missing_file" ));
473     QVERIFY(test_compiler.commandOutput().contains(warningMsg));
474
475     // test include() usage on a missing file when all function parameters are used
476     test_compiler.clearCommandOutput();
477     workDir = base_path + "/testdata/include_function";
478     QVERIFY(test_compiler.qmake( workDir, "include_missing_file2" ));
479     QVERIFY(test_compiler.commandOutput().contains(warningMsg));
480 }
481
482 void tst_qmake::substitutes()
483 {
484     QString workDir = base_path + "/testdata/substitutes";
485     QVERIFY( test_compiler.qmake( workDir, "test" ));
486     QVERIFY( test_compiler.exists( workDir, "test", Plain, "" ));
487     QVERIFY( test_compiler.exists( workDir, "sub/test2", Plain, "" ));
488     QVERIFY( test_compiler.exists( workDir, "sub/indirect_test.txt", Plain, "" ));
489     QVERIFY( test_compiler.makeDistClean( workDir ));
490
491     QString buildDir = base_path + "/testdata/substitutes_build";
492     QVERIFY( test_compiler.qmake( workDir, "test", buildDir ));
493     QVERIFY( test_compiler.exists( buildDir, "test", Plain, "" ));
494     QVERIFY( test_compiler.exists( buildDir, "sub/test2", Plain, "" ));
495     QVERIFY( test_compiler.exists( buildDir, "sub/indirect_test.txt", Plain, "" ));
496     QVERIFY( test_compiler.makeDistClean( buildDir ));
497 }
498
499 QTEST_MAIN(tst_qmake)
500 #include "tst_qmake.moc"
501
502 #else // QMAKE_CROSS_COMPILED
503 QTEST_NOOP_MAIN
504 #endif