1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "tst_qmakelib.h"
30
31#include <proitems.h>
32#include <qmakevfs.h>
33#include <qmakeparser.h>
34#include <qmakeglobals.h>
35#include <qmakeevaluator.h>
36
37#ifdef Q_OS_WIN
38# define EVAL_DRIVE "R:"
39#else
40# define EVAL_DRIVE
41#endif
42
43void tst_qmakelib::addAssignments()
44{
45 QTest::newRow(dataTag: "assignment")
46 << "VAR = foo bar baz"
47 << "VAR = foo bar baz"
48 << ""
49 << true;
50
51 QTest::newRow(dataTag: "appending")
52 << "VAR = foo bar baz\nVAR += foo gaz gaz"
53 << "VAR = foo bar baz foo gaz gaz"
54 << ""
55 << true;
56
57 QTest::newRow(dataTag: "unique appending")
58 << "VAR = foo bar baz\nVAR *= foo gaz gaz"
59 << "VAR = foo bar baz gaz"
60 << ""
61 << true;
62
63 QTest::newRow(dataTag: "removing")
64 << "VAR = foo bar foo baz\nVAR -= foo gaz gaz"
65 << "VAR = bar baz"
66 << ""
67 << true;
68
69 // Somewhat unexpectedly, the g modifier is implicit within each element.
70 QTest::newRow(dataTag: "replacing")
71 << "VAR = foo bar foo baz\nVAR ~= s,o,0,"
72 << "VAR = f00 bar foo baz"
73 << ""
74 << true;
75
76 // Consistently with the "there are no empty elements", what becomes empty gets zapped.
77 QTest::newRow(dataTag: "replacing with nothing")
78 << "VAR = foo bar foo baz\nVAR ~= s,foo,,"
79 << "VAR = bar foo baz"
80 << ""
81 << true;
82
83 QTest::newRow(dataTag: "replacing case-insensitively")
84 << "VAR = foO bar foo baz\nVAR ~= s,o,0,i"
85 << "VAR = f00 bar foo baz"
86 << ""
87 << true;
88
89 // In all elements, not all within each/one/??? element.
90 QTest::newRow(dataTag: "replacing globally")
91 << "VAR = foo bar foo baz\nVAR ~= s,o,0,g"
92 << "VAR = f00 bar f00 baz"
93 << ""
94 << true;
95
96 // Replacing with the same string counts as no match.
97 // This is rather questionable ...
98 QTest::newRow(dataTag: "replacing with same")
99 << "VAR = foo bar foo baz\nVAR ~= s,ba[rz],bar,"
100 << "VAR = foo bar foo bar"
101 << ""
102 << true;
103
104 QTest::newRow(dataTag: "replacing with auto-quote")
105 << "VAR = foo [bar] foo baz\nVAR ~= s,[bar],bar,q"
106 << "VAR = foo bar foo baz"
107 << ""
108 << true;
109
110 QTest::newRow(dataTag: "replacing with expansions")
111 << "VAR = foo bar foo baz\nPAT = foo\nREPL = 'yee haw'\nVAR ~= s,$$PAT,$$REPL,"
112 << "VAR = 'yee haw' bar foo baz"
113 << ""
114 << true;
115
116 QTest::newRow(dataTag: "~= with bad function")
117 << "VAR ~= m/foo/"
118 << ""
119 << "##:1: The ~= operator can handle only the s/// function."
120 << true; // rather questionable
121
122 QTest::newRow(dataTag: "~= s with bad number of arguments")
123 << "VAR ~= s/bla\nVAR ~= s/bla/foo//"
124 << ""
125 << "##:1: The s/// function expects 3 or 4 arguments.\n"
126 "##:2: The s/// function expects 3 or 4 arguments."
127 << true; // rather questionable
128}
129
130void tst_qmakelib::addExpansions()
131{
132 QTest::newRow(dataTag: "expand variable")
133 << "V1 = foo\nVAR = $$V1"
134 << "VAR = foo"
135 << ""
136 << true;
137
138 QTest::newRow(dataTag: "expand property")
139 << "VAR = $$[P1]"
140 << "VAR = 'prop val'"
141 << ""
142 << true;
143
144 QTest::newRow(dataTag: "expand environment variable")
145 << "VAR = $$(E1)"
146 << "VAR = 'env var'"
147 << ""
148 << true;
149
150 // These test addStr/addStr.
151
152 QTest::newRow(dataTag: "expand: str $$(env)")
153 << "VAR = foo $$(E1)"
154 << "VAR = foo 'env var'"
155 << ""
156 << true;
157
158 QTest::newRow(dataTag: "expand: str$$(env)")
159 << "VAR = foo$$(E1)"
160 << "VAR = 'fooenv var'"
161 << ""
162 << true;
163
164 QTest::newRow(dataTag: "expand: 'str $$(env)'")
165 << "VAR = 'foo $$(E1)'"
166 << "VAR = 'foo env var'"
167 << ""
168 << true;
169
170 // These test addStr/addStrList
171
172 QTest::newRow(dataTag: "expand: str $$var")
173 << "V1 = foo barbaz\nVAR = str $$V1"
174 << "VAR = str foo barbaz"
175 << ""
176 << true;
177
178 QTest::newRow(dataTag: "expand: $$var str")
179 << "V1 = foo barbaz\nVAR = $$V1 str"
180 << "VAR = foo barbaz str"
181 << ""
182 << true;
183
184 QTest::newRow(dataTag: "expand: str$$var")
185 << "V1 = foo barbaz\nVAR = str$$V1"
186 << "VAR = strfoo barbaz"
187 << ""
188 << true;
189
190 QTest::newRow(dataTag: "expand: $${var}str")
191 << "V1 = foo barbaz\nVAR = $${V1}str"
192 << "VAR = foo barbazstr"
193 << ""
194 << true;
195
196 QTest::newRow(dataTag: "expand: 'str $$var'")
197 << "V1 = foo barbaz\nVAR = 'str $$V1'"
198 << "VAR = 'str foo barbaz'"
199 << ""
200 << true;
201
202 QTest::newRow(dataTag: "expand: '$$var str'")
203 << "V1 = foo barbaz\nVAR = '$$V1 str'"
204 << "VAR = 'foo barbaz str'"
205 << ""
206 << true;
207
208 // Same again in joined context
209
210 QTest::newRow(dataTag: "expand joined: str $$(env)")
211 << "VAR = $$quote(foo $$(E1))"
212 << "VAR = 'foo env var'"
213 << ""
214 << true;
215
216 QTest::newRow(dataTag: "expand joined: str$$(env)")
217 << "VAR = $$quote(foo$$(E1))"
218 << "VAR = 'fooenv var'"
219 << ""
220 << true;
221
222 QTest::newRow(dataTag: "expand joined: 'str $$(env)'")
223 << "VAR = $$quote('foo $$(E1)')"
224 << "VAR = 'foo env var'"
225 << ""
226 << true;
227
228 QTest::newRow(dataTag: "expand joined: str $$var")
229 << "V1 = foo barbaz\nVAR = $$quote(str $$V1)"
230 << "VAR = 'str foo barbaz'"
231 << ""
232 << true;
233
234 QTest::newRow(dataTag: "expand joined: $$var str")
235 << "V1 = foo barbaz\nVAR = $$quote($$V1 str)"
236 << "VAR = 'foo barbaz str'"
237 << ""
238 << true;
239
240 QTest::newRow(dataTag: "expand joined: str$$var")
241 << "V1 = foo barbaz\nVAR = $$quote(str$$V1)"
242 << "VAR = 'strfoo barbaz'"
243 << ""
244 << true;
245
246 QTest::newRow(dataTag: "expand joined: $${var}str")
247 << "V1 = foo barbaz\nVAR = $$quote($${V1}str)"
248 << "VAR = 'foo barbazstr'"
249 << ""
250 << true;
251
252 QTest::newRow(dataTag: "expand joined: 'str $$var'")
253 << "V1 = foo barbaz\nVAR = $$quote('str $$V1')"
254 << "VAR = 'str foo barbaz'"
255 << ""
256 << true;
257
258 QTest::newRow(dataTag: "expand joined: '$$var str'")
259 << "V1 = foo barbaz\nVAR = $$quote('$$V1 str')"
260 << "VAR = 'foo barbaz str'"
261 << ""
262 << true;
263
264 // Variable expansions on LHS
265
266 QTest::newRow(dataTag: "indirect assign: $$var")
267 << "V = VAR\n$$V = foo"
268 << "VAR = foo"
269 << ""
270 << true;
271
272 QTest::newRow(dataTag: "indirect assign: fix$$var")
273 << "V = AR\nV$$V = foo"
274 << "VAR = foo"
275 << ""
276 << true;
277
278 QTest::newRow(dataTag: "indirect assign: $${var}fix")
279 << "V = VA\n$${V}R = foo"
280 << "VAR = foo"
281 << ""
282 << true;
283
284 QTest::newRow(dataTag: "indirect assign: eval")
285 << "V = VAR\n$$eval(V) = foo"
286 << "VAR = foo"
287 << ""
288 << true;
289
290 QTest::newRow(dataTag: "indirect assign: multiple")
291 << "V = FOO BAR\n$$V = foo"
292 << ""
293 << "##:2: Left hand side of assignment must expand to exactly one word."
294 << true;
295}
296
297void tst_qmakelib::addControlStructs()
298{
299 QTest::newRow(dataTag: "true")
300 << "true: VAR = 1"
301 << "VAR = 1"
302 << ""
303 << true;
304
305 QTest::newRow(dataTag: "false")
306 << "false: VAR = 1"
307 << "VAR = UNDEF"
308 << ""
309 << true;
310
311 QTest::newRow(dataTag: "true-config")
312 << "CONFIG += test\ntest: VAR = 1"
313 << "VAR = 1"
314 << ""
315 << true;
316
317 QTest::newRow(dataTag: "false-config")
318 << "test: VAR = 1"
319 << "VAR = UNDEF"
320 << ""
321 << true;
322
323 QTest::newRow(dataTag: "true-wildcard")
324 << "CONFIG += testing\ntest*: VAR = 1"
325 << "VAR = 1"
326 << ""
327 << true;
328
329 QTest::newRow(dataTag: "false-wildcard")
330 << "test*: VAR = 1"
331 << "VAR = UNDEF"
332 << ""
333 << true;
334
335 QTest::newRow(dataTag: "true-else")
336 << "true: VAR1 = 1\nelse: VAR2 = 1"
337 << "VAR1 = 1\nVAR2 = UNDEF"
338 << ""
339 << true;
340
341 QTest::newRow(dataTag: "false-else")
342 << "false: VAR1 = 1\nelse: VAR2 = 1"
343 << "VAR1 = UNDEF\nVAR2 = 1"
344 << ""
345 << true;
346
347 QTest::newRow(dataTag: "true-else-true-else")
348 << "true: VAR1 = 1\nelse: true: VAR2 = 1\nelse: VAR3 = 1"
349 << "VAR1 = 1\nVAR2 = UNDEF\nVAR3 = UNDEF"
350 << ""
351 << true;
352
353 QTest::newRow(dataTag: "true-else-false-else")
354 << "true: VAR1 = 1\nelse: false: VAR2 = 1\nelse: VAR3 = 1"
355 << "VAR1 = 1\nVAR2 = UNDEF\nVAR3 = UNDEF"
356 << ""
357 << true;
358
359 QTest::newRow(dataTag: "false-else-true-else")
360 << "false: VAR1 = 1\nelse: true: VAR2 = 1\nelse: VAR3 = 1"
361 << "VAR1 = UNDEF\nVAR2 = 1\nVAR3 = UNDEF"
362 << ""
363 << true;
364
365 QTest::newRow(dataTag: "false-else-false-else")
366 << "false: VAR1 = 1\nelse: false: VAR2 = 1\nelse: VAR3 = 1"
367 << "VAR1 = UNDEF\nVAR2 = UNDEF\nVAR3 = 1"
368 << ""
369 << true;
370
371 QTest::newRow(dataTag: "true-{false-else}-else")
372 << "true {\nfalse: VAR1 = 1\nelse: VAR2 = 1\n}\nelse: VAR3 = 1"
373 << "VAR1 = UNDEF\nVAR2 = 1\nVAR3 = UNDEF"
374 << ""
375 << true;
376
377 QTest::newRow(dataTag: "NOT-true")
378 << "!true: VAR = 1"
379 << "VAR = UNDEF"
380 << ""
381 << true;
382
383 QTest::newRow(dataTag: "NOT-false")
384 << "!false: VAR = 1"
385 << "VAR = 1"
386 << ""
387 << true;
388
389 QTest::newRow(dataTag: "true-AND-true")
390 << "true:true: VAR = 1"
391 << "VAR = 1"
392 << ""
393 << true;
394
395 QTest::newRow(dataTag: "true-AND-false")
396 << "true:false: VAR = 1"
397 << "VAR = UNDEF"
398 << ""
399 << true;
400
401 QTest::newRow(dataTag: "false-AND-true")
402 << "false:true: VAR = 1"
403 << "VAR = UNDEF"
404 << ""
405 << true;
406
407 QTest::newRow(dataTag: "false-OR-false")
408 << "false|false: VAR = 1"
409 << "VAR = UNDEF"
410 << ""
411 << true;
412
413 QTest::newRow(dataTag: "true-OR-false")
414 << "true|false: VAR = 1"
415 << "VAR = 1"
416 << ""
417 << true;
418
419 QTest::newRow(dataTag: "false-OR-true")
420 << "false|true: VAR = 1"
421 << "VAR = 1"
422 << ""
423 << true;
424
425 QTest::newRow(dataTag: "NOT-false-AND-true")
426 << "!false:true: VAR = 1"
427 << "VAR = 1"
428 << ""
429 << true;
430
431 QTest::newRow(dataTag: "true-AND-message")
432 << "true:message(hi): VAR = 1"
433 << "VAR = 1"
434 << "Project MESSAGE: hi"
435 << true;
436
437 QTest::newRow(dataTag: "false-AND-message")
438 << "false:message(hi): VAR = 1"
439 << "VAR = UNDEF"
440 << ""
441 << true;
442
443 QTest::newRow(dataTag: "true-OR-message")
444 << "true|message(hi): VAR = 1"
445 << "VAR = 1"
446 << ""
447 << true;
448
449 QTest::newRow(dataTag: "false-OR-message")
450 << "false|message(hi): VAR = 1"
451 << "VAR = 1"
452 << "Project MESSAGE: hi"
453 << true;
454
455 QTest::newRow(dataTag: "true-OR-message-AND-false")
456 << "true|message(hi):false: VAR = 1"
457 << "VAR = UNDEF"
458 << ""
459 << true;
460
461 QTest::newRow(dataTag: "false-OR-message-AND-false")
462 << "false|message(hi):false: VAR = 1"
463 << "VAR = UNDEF"
464 << "Project MESSAGE: hi"
465 << true;
466
467 QTest::newRow(dataTag: "true (indirect)")
468 << "TEST = true\n$$TEST: VAR = 1"
469 << "VAR = 1"
470 << ""
471 << true;
472
473 QTest::newRow(dataTag: "false (indirect)")
474 << "TEST = false\n$$TEST: VAR = 1"
475 << "VAR = UNDEF"
476 << ""
477 << true;
478
479 // Yes, this is not supposed to work
480 QTest::newRow(dataTag: "true|false (indirect)")
481 << "TEST = true|false\n$$TEST: VAR = 1"
482 << "VAR = UNDEF"
483 << ""
484 << true;
485
486 QTest::newRow(dataTag: "for (var, var)")
487 << "IN = one two three\nfor (IT, IN) { OUT += $$IT }"
488 << "OUT = one two three"
489 << ""
490 << true;
491
492 QTest::newRow(dataTag: "for (var, range)")
493 << "for (IT, 1..3) { OUT += $$IT }"
494 << "OUT = 1 2 3"
495 << ""
496 << true;
497
498 QTest::newRow(dataTag: "for (var, reverse-range)")
499 << "for (IT, 3..1) { OUT += $$IT }"
500 << "OUT = 3 2 1"
501 << ""
502 << true;
503
504 // This syntax is rather ridiculous.
505 QTest::newRow(dataTag: "for (ever)")
506 << "for (ever) {}"
507 << ""
508 << "##:1: Ran into infinite loop (> 1000 iterations)."
509 << true;
510
511 // This is even worse.
512 QTest::newRow(dataTag: "for (VAR, forever)")
513 << "for (VAR, forever) { OUT = $$VAR }"
514 << "OUT = 999"
515 << "##:1: Ran into infinite loop (> 1000 iterations)."
516 << true;
517
518 QTest::newRow(dataTag: "for (garbage)")
519 << "for (garbage) { OUT = FAIL }"
520 << "OUT = UNDEF"
521 << "##:1: Invalid loop expression."
522 << true;
523
524 QTest::newRow(dataTag: "next()")
525 << "IN = one two three\nfor (IT, IN) {\nequals(IT, two):next()\nOUT += $$IT\n}"
526 << "OUT = one three"
527 << ""
528 << true;
529
530 QTest::newRow(dataTag: "nested next()")
531 << "IN = one two three\nfor (IT, IN) {\nfor (NIT, IN):next()\nOUT += $$IT\n}"
532 << "OUT = one two three"
533 << ""
534 << true;
535
536 QTest::newRow(dataTag: "break()")
537 << "IN = one two three\nfor (IT, IN) {\nequals(IT, three):break()\nOUT += $$IT\n}"
538 << "OUT = one two"
539 << ""
540 << true;
541
542 QTest::newRow(dataTag: "nested break()")
543 << "IN = one two three\nfor (IT, IN) {\nfor (NIT, IN):break()\nOUT += $$IT\n}"
544 << "OUT = one two three"
545 << ""
546 << true;
547
548 QTest::newRow(dataTag: "defineReplace()")
549 << "defineReplace(func) { return($$1 + $$2) }\n"
550 "VAR = $$func(test me, \"foo bar\")"
551 << "VAR = test me + 'foo bar'"
552 << ""
553 << true;
554
555 QTest::newRow(dataTag: "defineTest()")
556 << "defineTest(func) { return($$1) }\n"
557 "func(true): VAR += true\n"
558 "func(false): VAR += false"
559 << "VAR = true"
560 << ""
561 << true;
562
563 QTest::newRow(dataTag: "true-AND-defineTest()")
564 << "true: defineTest(func)\n"
565 "defined(func): OK = 1"
566 << "OK = 1"
567 << ""
568 << true;
569
570 QTest::newRow(dataTag: "false-AND-defineTest()")
571 << "false: defineTest(func)\n"
572 "defined(func): OK = 1"
573 << "OK = UNDEF"
574 << ""
575 << true;
576
577 QTest::newRow(dataTag: "true-OR-defineTest()")
578 << "true| defineTest(func)\n"
579 "defined(func): OK = 1"
580 << "OK = UNDEF"
581 << ""
582 << true;
583
584 QTest::newRow(dataTag: "false-OR-defineTest()")
585 << "false| defineTest(func)\n"
586 "defined(func): OK = 1"
587 << "OK = 1"
588 << ""
589 << true;
590
591 QTest::newRow(dataTag: "variable scoping")
592 << "defineTest(func) {\n"
593 "VAR1 = modified\n!equals(VAR1, modified): return(false)\n"
594 "VAR2 += modified\n!equals(VAR2, original modified): return(false)\n"
595 "VAR3 = new var\n!equals(VAR3, new var): return(false)\n"
596 "return(true)\n"
597 "}\n"
598 "VAR1 = pristine\nVAR2 = original\nfunc(): OK = 1"
599 << "OK = 1\nVAR1 = pristine\nVAR2 = original\nVAR3 = UNDEF"
600 << ""
601 << true;
602
603 QTest::newRow(dataTag: "function arguments")
604 << "defineTest(func) {\n"
605 "defined(1, var) {\nd1 = 1\nexport(d1)\n}\n"
606 "defined(3, var) {\nd3 = 1\nexport(d3)\n}\n"
607 "x1 = $$1\nexport(x1)\n"
608 "2 += foo\nx2 = $$2\nexport(x2)\n"
609 "x3 = $$3\nexport(x3)\n"
610 "4 += foo\nx4 = $$4\nexport(x4)\n"
611 "x5 = $$5\nexport(x5)\n"
612 "6 += foo\nx6 = $$6\nexport(x6)\n"
613 "}\n"
614 "1 = first\n2 = second\n3 = third\n4 = fourth\nfunc(one, two)"
615 << "1 = first\n2 = second\n3 = third\n4 = fourth\n5 = UNDEF\n6 = UNDEF\n"
616 "d1 = 1\nd3 = UNDEF\nx1 = one\nx2 = two foo\nx3 =\nx4 = foo\nx5 =\nx6 = foo"
617 << ""
618 << true;
619
620 QTest::newRow(dataTag: "ARGC and ARGS")
621 << "defineTest(func) {\n"
622 "export(ARGC)\n"
623 "export(ARGS)\n"
624 "}\n"
625 "func(test me, \"foo bar\")"
626 << "ARGC = 2\nARGS = test me 'foo bar'"
627 << ""
628 << true;
629
630 QTest::newRow(dataTag: "recursion")
631 << "defineReplace(func) {\n"
632 "RET = *$$member(1, 0)*\n"
633 "REST = $$member(1, 1, -1)\n"
634 "!isEmpty(REST): RET += $$func($$REST)\n"
635 "return($$RET)\n"
636 "}\n"
637 "VAR = $$func(you are ...)"
638 << "VAR = *you* *are* *...*"
639 << ""
640 << true;
641
642 QTest::newRow(dataTag: "bypassNesting()")
643 << "defineTest(func) {\n"
644 "LOCAL = 1\n"
645 "bypassNesting() {\n"
646 "OUT = 1\n"
647 "!isEmpty(GLOBAL): OUT1 = 1\n"
648 "!isEmpty(LOCAL): OUT2 = 1\n"
649 "}\n"
650 "}\n"
651 "GLOBAL = 1\n"
652 "func()"
653 << "GLOBAL = 1\nLOCAL = UNDEF\nOUT = 1\nOUT1 = 1\nOUT2 = UNDEF"
654 << ""
655 << true;
656
657 QTest::newRow(dataTag: "error() from bypassNesting()")
658 << "defineTest(func) {\n"
659 "bypassNesting() { error(error) }\n"
660 "}\n"
661 "func()\n"
662 "OKE = 1"
663 << "OKE = UNDEF"
664 << "Project ERROR: error"
665 << false;
666
667 QTest::newRow(dataTag: "top-level return()")
668 << "VAR = good\nreturn()\nVAR = bad"
669 << "VAR = good"
670 << ""
671 << true;
672
673 QTest::newRow(dataTag: "return() from function")
674 << "defineTest(func) {\nVAR = good\nexport(VAR)\nreturn()\nVAR = bad\nexport(VAR)\n}\n"
675 "func()"
676 << "VAR = good"
677 << ""
678 << true;
679
680 QTest::newRow(dataTag: "return() from nested function")
681 << "defineTest(inner) {\nVAR = initial\nexport(VAR)\nreturn()\nVAR = bad\nexport(VAR)\n}\n"
682 "defineTest(outer) {\ninner()\nVAR = final\nexport(VAR)\n}\n"
683 "outer()"
684 << "VAR = final"
685 << ""
686 << true;
687
688 QTest::newRow(dataTag: "error() from replace function (assignment)")
689 << "defineReplace(func) {\nerror(error)\n}\n"
690 "VAR = $$func()\n"
691 "OKE = 1"
692 << "VAR = UNDEF\nOKE = UNDEF"
693 << "Project ERROR: error"
694 << false;
695
696 QTest::newRow(dataTag: "error() from replace function (replacement)")
697 << "defineReplace(func) {\nerror(error)\n}\n"
698 "VAR = $$func()\n"
699 "OKE = 1"
700 << "VAR = UNDEF\nOKE = UNDEF"
701 << "Project ERROR: error"
702 << false;
703
704 QTest::newRow(dataTag: "error() from replace function (LHS)")
705 << "defineReplace(func) {\nerror(error)\nreturn(VAR)\n}\n"
706 "$$func() = 1\n"
707 "OKE = 1"
708 << "VAR = UNDEF\nOKE = UNDEF"
709 << "Project ERROR: error"
710 << false;
711
712 QTest::newRow(dataTag: "error() from replace function (loop variable)")
713 << "defineReplace(func) {\nerror(error)\nreturn(BLAH)\n}\n"
714 "for($$func()) {\nVAR = $$BLAH\nbreak()\n}\n"
715 "OKE = 1"
716 << "VAR = UNDEF\nOKE = UNDEF"
717 << "Project ERROR: error"
718 << false;
719
720 QTest::newRow(dataTag: "error() from replace function (built-in test arguments)")
721 << "defineReplace(func) {\nerror(error)\n}\n"
722 "message($$func()): VAR = 1\n"
723 "OKE = 1"
724 << "VAR = UNDEF\nOKE = UNDEF"
725 << "Project ERROR: error"
726 << false;
727
728 QTest::newRow(dataTag: "error() from replace function (built-in replace arguments)")
729 << "defineReplace(func) {\nerror(error)\n}\n"
730 "VAR = $$upper($$func())\n"
731 "OKE = 1"
732 << "VAR = UNDEF\nOKE = UNDEF"
733 << "Project ERROR: error"
734 << false;
735
736 QTest::newRow(dataTag: "error() from replace function (custom test arguments)")
737 << "defineReplace(func) {\nerror(error)\n}\n"
738 "defineTest(custom) {\n}\n"
739 "custom($$func()): VAR = 1\n"
740 "OKE = 1"
741 << "VAR = UNDEF\nOKE = UNDEF"
742 << "Project ERROR: error"
743 << false;
744
745 QTest::newRow(dataTag: "error() from replace function (custom replace arguments)")
746 << "defineReplace(func) {\nerror(error)\nreturn(1)\n}\n"
747 "defineReplace(custom) {\nreturn($$1)\n}\n"
748 "VAR = $$custom($$func(1))\n"
749 "OKE = 1"
750 << "VAR = UNDEF\nOKE = UNDEF"
751 << "Project ERROR: error"
752 << false;
753
754 QTest::newRow(dataTag: "REQUIRES = error()")
755 << "REQUIRES = error(error)\n"
756 "OKE = 1"
757 << "OKE = UNDEF"
758 << "Project ERROR: error"
759 << false;
760
761 QTest::newRow(dataTag: "requires(error())")
762 << "requires(error(error))\n"
763 "OKE = 1"
764 << "OKE = UNDEF"
765 << "Project ERROR: error"
766 << false;
767}
768
769void tst_qmakelib::addReplaceFunctions(const QString &qindir)
770{
771 QTest::newRow(dataTag: "$$member(): empty")
772 << "IN = \nVAR = $$member(IN)"
773 << "VAR ="
774 << ""
775 << true;
776
777 QTest::newRow(dataTag: "$$member(): too short")
778 << "IN = one two three\nVAR = $$member(IN, 1, 5)"
779 << "VAR =" // this is actually kinda stupid
780 << ""
781 << true;
782
783 QTest::newRow(dataTag: "$$member(): ok")
784 << "IN = one two three four five six seven\nVAR = $$member(IN, 1, 4)"
785 << "VAR = two three four five"
786 << ""
787 << true;
788
789 QTest::newRow(dataTag: "$$member(): ok (default start)")
790 << "IN = one two three\nVAR = $$member(IN)"
791 << "VAR = one"
792 << ""
793 << true;
794
795 QTest::newRow(dataTag: "$$member(): ok (default end)")
796 << "IN = one two three\nVAR = $$member(IN, 2)"
797 << "VAR = three"
798 << ""
799 << true;
800
801 QTest::newRow(dataTag: "$$member(): negative")
802 << "IN = one two three four five six seven\nVAR = $$member(IN, -4, -3)"
803 << "VAR = four five"
804 << ""
805 << true;
806
807 QTest::newRow(dataTag: "$$member(): inverse")
808 << "IN = one two three four five six seven\nVAR = $$member(IN, 4, 1)"
809 << "VAR = five four three two"
810 << ""
811 << true;
812
813 QTest::newRow(dataTag: "$$member(): dots")
814 << "IN = one two three four five six seven\nVAR = $$member(IN, 1..4)"
815 << "VAR = two three four five"
816 << ""
817 << true;
818
819 QTest::newRow(dataTag: "$$member(): bad number of arguments")
820 << "VAR = $$member(1, 2, 3, 4)"
821 << "VAR ="
822 << "##:1: member(var, [start, [end]]) requires one to three arguments."
823 << true;
824
825 QTest::newRow(dataTag: "$$member(): bad args (1)")
826 << "IN = one two three\nVAR = $$member(IN, foo, 4)"
827 << "VAR ="
828 << "##:2: member() argument 2 (start) 'foo' invalid."
829 << true;
830
831 QTest::newRow(dataTag: "$$member(): bad args (2)")
832 << "IN = one two three\nVAR = $$member(IN, foo..4)"
833 << "VAR ="
834 << "##:2: member() argument 2 (start) 'foo..4' invalid."
835 << true;
836
837 QTest::newRow(dataTag: "$$member(): bad args (3)")
838 << "IN = one two three\nVAR = $$member(IN, 4, foo)"
839 << "VAR ="
840 << "##:2: member() argument 3 (end) 'foo' invalid."
841 << true;
842
843 QTest::newRow(dataTag: "$$member(): bad args (4)")
844 << "IN = one two three\nVAR = $$member(IN, 4..foo)"
845 << "VAR ="
846 << "##:2: member() argument 2 (start) '4..foo' invalid."
847 << true;
848
849 // The argument processing is shared with $$member(), so some tests are skipped.
850 QTest::newRow(dataTag: "$$str_member(): empty")
851 << "VAR = $$str_member()"
852 << "VAR ="
853 << ""
854 << true;
855
856 QTest::newRow(dataTag: "$$str_member(): too short")
857 << "VAR = $$str_member(string_value, 7, 12)"
858 << "VAR =" // this is actually kinda stupid
859 << ""
860 << true;
861
862 QTest::newRow(dataTag: "$$str_member(): ok")
863 << "VAR = $$str_member(string_value, 7, 11)"
864 << "VAR = value"
865 << ""
866 << true;
867
868 QTest::newRow(dataTag: "$$str_member(): ok (default start)")
869 << "VAR = $$str_member(string_value)"
870 << "VAR = s"
871 << ""
872 << true;
873
874 QTest::newRow(dataTag: "$$str_member(): ok (default end)")
875 << "VAR = $$str_member(string_value, 7)"
876 << "VAR = v"
877 << ""
878 << true;
879
880 QTest::newRow(dataTag: "$$str_member(): negative")
881 << "VAR = $$str_member(string_value, -5, -3)"
882 << "VAR = val"
883 << ""
884 << true;
885
886 QTest::newRow(dataTag: "$$str_member(): inverse")
887 << "VAR = $$str_member(string_value, -2, 1)"
888 << "VAR = ulav_gnirt"
889 << ""
890 << true;
891
892 QTest::newRow(dataTag: "$$first(): empty")
893 << "IN = \nVAR = $$first(IN)"
894 << "VAR ="
895 << ""
896 << true;
897
898 QTest::newRow(dataTag: "$$first(): one")
899 << "IN = one\nVAR = $$first(IN)"
900 << "VAR = one"
901 << ""
902 << true;
903
904 QTest::newRow(dataTag: "$$first(): multiple")
905 << "IN = one two three\nVAR = $$first(IN)"
906 << "VAR = one"
907 << ""
908 << true;
909
910 QTest::newRow(dataTag: "$$first(): bad number of arguments")
911 << "VAR = $$first(1, 2)"
912 << "VAR ="
913 << "##:1: first(var) requires one argument."
914 << true;
915
916 QTest::newRow(dataTag: "$$take_first(): empty")
917 << "IN = \nVAR = $$take_first(IN)"
918 << "VAR =\nIN ="
919 << ""
920 << true;
921
922 QTest::newRow(dataTag: "$$take_first(): one")
923 << "IN = one\nVAR = $$take_first(IN)"
924 << "VAR = one\nIN ="
925 << ""
926 << true;
927
928 QTest::newRow(dataTag: "$$take_first(): multiple")
929 << "IN = one two three\nVAR = $$take_first(IN)"
930 << "VAR = one\nIN = two three"
931 << ""
932 << true;
933
934 QTest::newRow(dataTag: "$$take_first(): bad number of arguments")
935 << "VAR = $$take_first(1, 2)"
936 << "VAR ="
937 << "##:1: take_first(var) requires one argument."
938 << true;
939
940 QTest::newRow(dataTag: "$$last(): empty")
941 << "IN = \nVAR = $$last(IN)"
942 << "VAR ="
943 << ""
944 << true;
945
946 QTest::newRow(dataTag: "$$last(): one")
947 << "IN = one\nVAR = $$last(IN)"
948 << "VAR = one"
949 << ""
950 << true;
951
952 QTest::newRow(dataTag: "$$last(): multiple")
953 << "IN = one two three\nVAR = $$last(IN)"
954 << "VAR = three"
955 << ""
956 << true;
957
958 QTest::newRow(dataTag: "$$last(): bad number of arguments")
959 << "VAR = $$last(1, 2)"
960 << "VAR ="
961 << "##:1: last(var) requires one argument."
962 << true;
963
964 QTest::newRow(dataTag: "$$take_last(): empty")
965 << "IN = \nVAR = $$take_last(IN)"
966 << "VAR =\nIN ="
967 << ""
968 << true;
969
970 QTest::newRow(dataTag: "$$take_last(): one")
971 << "IN = one\nVAR = $$take_last(IN)"
972 << "VAR = one\nIN ="
973 << ""
974 << true;
975
976 QTest::newRow(dataTag: "$$take_last(): multiple")
977 << "IN = one two three\nVAR = $$take_last(IN)"
978 << "VAR = three\nIN = one two"
979 << ""
980 << true;
981
982 QTest::newRow(dataTag: "$$take_last(): bad number of arguments")
983 << "VAR = $$take_last(1, 2)"
984 << "VAR ="
985 << "##:1: take_last(var) requires one argument."
986 << true;
987
988 QTest::newRow(dataTag: "$$size()")
989 << "IN = one two three\nVAR = $$size(IN)"
990 << "VAR = 3"
991 << ""
992 << true;
993
994 QTest::newRow(dataTag: "$$size(): bad number of arguments")
995 << "VAR = $$size(1, 2)"
996 << "VAR ="
997 << "##:1: size(var) requires one argument."
998 << true;
999
1000 QTest::newRow(dataTag: "$$str_size()")
1001 << "VAR = $$str_size(one two three)"
1002 << "VAR = 13"
1003 << ""
1004 << true;
1005
1006 QTest::newRow(dataTag: "$$str_size(): bad number of arguments")
1007 << "VAR = $$str_size(1, 2)"
1008 << "VAR ="
1009 << "##:1: str_size(str) requires one argument."
1010 << true;
1011
1012 QTest::newRow(dataTag: "$$fromfile(): right var")
1013 << "VAR = $$fromfile(" + qindir + "/fromfile/infile.prx, DEFINES)"
1014 << "VAR = QT_DLL"
1015 << ""
1016 << true;
1017
1018 QTest::newRow(dataTag: "$$fromfile(): wrong var")
1019 << "VAR = $$fromfile(" + qindir + "/fromfile/infile.prx, INCLUDES)"
1020 << "VAR ="
1021 << ""
1022 << true;
1023
1024 QTest::newRow(dataTag: "$$fromfile(): bad file")
1025 << "VAR = $$fromfile(" + qindir + "/fromfile/badfile.prx, DEFINES)"
1026 << "VAR ="
1027 << "Project ERROR: fail!"
1028 << true;
1029
1030 QTest::newRow(dataTag: "$$fromfile(): bad number of arguments")
1031 << "VAR = $$fromfile(1) \\\n$$fromfile(1, 2, 3)"
1032 << "VAR ="
1033 << "##:1: fromfile(file, var) requires two arguments.\n"
1034 "##:2: fromfile(file, var) requires two arguments."
1035 << true;
1036
1037 QTest::newRow(dataTag: "$$eval()")
1038 << "IN = one two three\nVAR = $$eval(IN)"
1039 << "VAR = one two three"
1040 << ""
1041 << true;
1042
1043 QTest::newRow(dataTag: "$$eval(): bad number of arguments")
1044 << "VAR = $$eval(1, 2)"
1045 << "VAR ="
1046 << "##:1: eval(var) requires one argument."
1047 << true;
1048
1049 QTest::newRow(dataTag: "$$list()")
1050 << "VARNAME = $$list(one, two three, 'four five')\nVAR = $$eval($$VARNAME)"
1051 << "VAR = one two three four five" // total nonsense ...
1052 << ""
1053 << true;
1054
1055 QTest::newRow(dataTag: "$$sprintf()")
1056 << "VAR = $$sprintf(hello %1 %2, you, there)"
1057 << "VAR = 'hello you there'"
1058 << ""
1059 << true;
1060
1061 QTest::newRow(dataTag: "$$format_number(): simple number format")
1062 << "VAR = $$format_number(13)"
1063 << "VAR = 13"
1064 << ""
1065 << true;
1066
1067 QTest::newRow(dataTag: "$$format_number(): negative number format")
1068 << "VAR = $$format_number(-13)"
1069 << "VAR = -13"
1070 << ""
1071 << true;
1072
1073 QTest::newRow(dataTag: "$$format_number(): hex input number format")
1074 << "VAR = $$format_number(13, ibase=16)"
1075 << "VAR = 19"
1076 << ""
1077 << true;
1078
1079 QTest::newRow(dataTag: "$$format_number(): hex output number format")
1080 << "VAR = $$format_number(13, obase=16)"
1081 << "VAR = d"
1082 << ""
1083 << true;
1084
1085 QTest::newRow(dataTag: "$$format_number(): right aligned number format")
1086 << "VAR = $$format_number(13, width=5)"
1087 << "VAR = ' 13'"
1088 << ""
1089 << true;
1090
1091 QTest::newRow(dataTag: "$$format_number(): left aligned number format")
1092 << "VAR = $$format_number(13, width=5 leftalign)"
1093 << "VAR = '13 '"
1094 << ""
1095 << true;
1096
1097 QTest::newRow(dataTag: "$$format_number(): zero-padded number format")
1098 << "VAR = $$format_number(13, width=5 zeropad)"
1099 << "VAR = 00013"
1100 << ""
1101 << true;
1102
1103 QTest::newRow(dataTag: "$$format_number(): always signed number format")
1104 << "VAR = $$format_number(13, width=5 alwayssign)"
1105 << "VAR = ' +13'"
1106 << ""
1107 << true;
1108
1109 QTest::newRow(dataTag: "$$format_number(): zero-padded always signed number format")
1110 << "VAR = $$format_number(13, width=5 alwayssign zeropad)"
1111 << "VAR = +0013"
1112 << ""
1113 << true;
1114
1115 QTest::newRow(dataTag: "$$format_number(): sign-padded number format")
1116 << "VAR = $$format_number(13, width=5 padsign)"
1117 << "VAR = ' 13'"
1118 << ""
1119 << true;
1120
1121 QTest::newRow(dataTag: "$$format_number(): zero-padded sign-padded number format")
1122
1123 << "VAR = $$format_number(13, width=5 padsign zeropad)"
1124 << "VAR = ' 0013'"
1125 << ""
1126 << true;
1127
1128 QTest::newRow(dataTag: "$$format_number(): bad number of arguments")
1129 << "VAR = $$format_number(13, 1, 2)"
1130 << "VAR ="
1131 << "##:1: format_number(number, [options...]) requires one or two arguments."
1132 << true;
1133
1134 QTest::newRow(dataTag: "$$format_number(): invalid option")
1135 << "VAR = $$format_number(13, foo=bar)"
1136 << "VAR ="
1137 << "##:1: format_number(): invalid format option foo=bar."
1138 << true;
1139
1140 QTest::newRow(dataTag: "$$num_add(): one")
1141 << "VAR = $$num_add(10)"
1142 << "VAR = 10"
1143 << ""
1144 << true;
1145
1146 QTest::newRow(dataTag: "$$num_add(): two")
1147 << "VAR = $$num_add(1, 2)"
1148 << "VAR = 3"
1149 << ""
1150 << true;
1151
1152 QTest::newRow(dataTag: "$$num_add(): three")
1153 << "VAR = $$num_add(1, 3, 5)"
1154 << "VAR = 9"
1155 << ""
1156 << true;
1157
1158 QTest::newRow(dataTag: "$$num_add(): negative")
1159 << "VAR = $$num_add(7, -13)"
1160 << "VAR = -6"
1161 << ""
1162 << true;
1163
1164 QTest::newRow(dataTag: "$$num_add(): bad number of arguments")
1165 << "VAR = $$num_add()"
1166 << "VAR = "
1167 << "##:1: num_add(num, ...) requires at least one argument."
1168 << true;
1169
1170 QTest::newRow(dataTag: "$$num_add(): bad number: float")
1171 << "VAR = $$num_add(1.1)"
1172 << "VAR ="
1173 << "##:1: num_add(): floats are currently not supported."
1174 << true;
1175
1176 QTest::newRow(dataTag: "$$num_add(): bad number: malformed")
1177 << "VAR = $$num_add(fail)"
1178 << "VAR ="
1179 << "##:1: num_add(): malformed number fail."
1180 << true;
1181
1182 QTest::newRow(dataTag: "$$join(): empty")
1183 << "IN = \nVAR = $$join(IN, //)"
1184 << "VAR ="
1185 << ""
1186 << true;
1187
1188 QTest::newRow(dataTag: "$$join(): multiple")
1189 << "IN = one two three\nVAR = $$join(IN, //)"
1190 << "VAR = one//two//three"
1191 << ""
1192 << true;
1193
1194 QTest::newRow(dataTag: "$$join(): multiple surrounded")
1195 << "IN = one two three\nVAR = $$join(IN, //, <<, >>)"
1196 << "VAR = <<one//two//three>>"
1197 << ""
1198 << true;
1199
1200 QTest::newRow(dataTag: "$$join(): bad number of arguments")
1201 << "VAR = $$join(1, 2, 3, 4, 5)"
1202 << "VAR ="
1203 << "##:1: join(var, [glue, [before, [after]]]) requires one to four arguments."
1204 << true;
1205
1206 QTest::newRow(dataTag: "$$split(): default sep")
1207 << "IN = 'one/two three' 'four / five'\nVAR = $$split(IN)"
1208 << "VAR = one/two three four / five"
1209 << ""
1210 << true;
1211
1212 QTest::newRow(dataTag: "$$split(): specified sep")
1213 << "IN = 'one/two three' 'four / five'\nVAR = $$split(IN, /)"
1214 << "VAR = one 'two three' 'four ' ' five'"
1215 << ""
1216 << true;
1217
1218 QTest::newRow(dataTag: "$$split(): bad number of arguments")
1219 << "VAR = $$split(1, 2, 3)"
1220 << "VAR ="
1221 << "##:1: split(var, sep) requires one or two arguments."
1222 << true;
1223
1224 QTest::newRow(dataTag: "$$basename(): empty")
1225 << "IN = \nVAR = $$basename(IN)"
1226 << "VAR ="
1227 << ""
1228 << true;
1229
1230 QTest::newRow(dataTag: "$$basename(): bare")
1231 << "IN = file\nVAR = $$basename(IN)"
1232 << "VAR = file"
1233 << ""
1234 << true;
1235
1236 QTest::newRow(dataTag: "$$basename(): relative")
1237 << "IN = path/file\nVAR = $$basename(IN)"
1238 << "VAR = file"
1239 << ""
1240 << true;
1241
1242 QTest::newRow(dataTag: "$$basename(): absolute")
1243 << "IN = \\\\path\\\\file\nVAR = $$basename(IN)"
1244 << "VAR = file"
1245 << ""
1246 << true;
1247
1248 QTest::newRow(dataTag: "$$basename(): bad number of arguments")
1249 << "VAR = $$basename(1, 2)"
1250 << "VAR ="
1251 << "##:1: basename(var) requires one argument."
1252 << true;
1253
1254 QTest::newRow(dataTag: "$$dirname(): empty")
1255 << "IN = \nVAR = $$dirname(IN)"
1256 << "VAR ="
1257 << ""
1258 << true;
1259
1260 QTest::newRow(dataTag: "$$dirname(): bare")
1261 << "IN = file\nVAR = $$dirname(IN)"
1262 << "VAR ="
1263 << ""
1264 << true;
1265
1266 QTest::newRow(dataTag: "$$dirname(): relative")
1267 << "IN = path/file\nVAR = $$dirname(IN)"
1268 << "VAR = path"
1269 << ""
1270 << true;
1271
1272 QTest::newRow(dataTag: "$$dirname(): absolute")
1273 << "IN = \\\\path\\\\file\nVAR = $$dirname(IN)"
1274 << "VAR = \\\\path"
1275 << ""
1276 << true;
1277
1278 QTest::newRow(dataTag: "$$dirname(): bad number of arguments")
1279 << "VAR = $$dirname(1, 2)"
1280 << "VAR ="
1281 << "##:1: dirname(var) requires one argument."
1282 << true;
1283
1284 QTest::newRow(dataTag: "$$section(): explicit end")
1285 << "IN = one~two~three~four~five~six\nVAR = $$section(IN, ~, 2, 4)"
1286 << "VAR = three~four~five"
1287 << ""
1288 << true;
1289
1290 QTest::newRow(dataTag: "$$section(): implicit end")
1291 << "IN = one~two~three~four~five~six\nVAR = $$section(IN, ~, 3)"
1292 << "VAR = four~five~six"
1293 << ""
1294 << true;
1295
1296 QTest::newRow(dataTag: "$$section(): bad number of arguments")
1297 << "VAR = $$section(1, 2) \\\n$$section(1, 2, 3, 4, 5)"
1298 << "VAR ="
1299 << "##:1: section(var, sep, begin, [end]) requires three or four arguments.\n"
1300 "##:2: section(var, sep, begin, [end]) requires three or four arguments."
1301 << true;
1302
1303 QTest::newRow(dataTag: "$$find()")
1304 << "IN = foo bar baz blubb\nVAR = $$find(IN, ^ba)"
1305 << "VAR = bar baz"
1306 << ""
1307 << true;
1308
1309 QTest::newRow(dataTag: "$$find(): bad number of arguments")
1310 << "VAR = $$find(1) \\\n$$find(1, 2, 3)"
1311 << "VAR ="
1312 << "##:1: find(var, str) requires two arguments.\n"
1313 "##:2: find(var, str) requires two arguments."
1314 << true;
1315
1316 // FIXME: $$cat() & $$system(): There is no way to generate the newlines
1317 // necessary for testing "multi-line" and "blob" mode adequately.
1318 // Note: these functions have *different* splitting behavior.
1319
1320 // This gives split_value_list() an exercise
1321 QTest::newRow(dataTag: "$$cat(): default mode")
1322 << "VAR = $$cat(" + qindir + "/cat/file2.txt)"
1323 << "VAR = foo bar baz \"\\\"Hello, \\' world.\\\"\" post \"\\'Hello, \\\" world.\\'\" post \\\\\\\" \\\\\\' \\\\\\\\ \\\\a \\\\ nix \"\\\" \\\"\""
1324 << ""
1325 << true;
1326
1327 QTest::newRow(dataTag: "$$cat(): lines mode")
1328 << "VAR = $$cat(" + qindir + "/cat/file1.txt, lines)"
1329 << "VAR = '\"Hello, world.\"' 'foo bar baz'"
1330 << ""
1331 << true;
1332
1333 QTest::newRow(dataTag: "$$cat(): bad number of arguments")
1334 << "VAR = $$cat(1, 2, 3)"
1335 << "VAR ="
1336 << "##:1: cat(file, [mode=true|blob|lines]) requires one or two arguments."
1337 << true;
1338
1339 QTest::newRow(dataTag: "$$system(): default mode")
1340#ifdef Q_OS_WIN
1341 << "VAR = $$system('echo Hello, ^\"world.&& echo foo^\" bar baz')"
1342#else
1343 << "VAR = $$system('echo Hello, \\\\\\\"world. && echo foo\\\\\\\" bar baz')"
1344#endif
1345 << "VAR = Hello, '\"world. foo\"' bar baz"
1346 << ""
1347 << true;
1348
1349 QTest::newRow(dataTag: "$$system(): lines mode")
1350#ifdef Q_OS_WIN
1351 << "VAR = $$system('echo Hello, ^\"world.&& echo foo^\" bar baz', lines)"
1352#else
1353 << "VAR = $$system('echo Hello, \\\\\\\"world. && echo foo\\\\\\\" bar baz', lines)"
1354#endif
1355 << "VAR = 'Hello, \"world.' 'foo\" bar baz'"
1356 << ""
1357 << true;
1358
1359 QTest::newRow(dataTag: "$$system(): bad number of arguments")
1360 << "VAR = $$system(1, 2, 3, 4)"
1361 << "VAR ="
1362 << "##:1: system(command, [mode], [stsvar]) requires one to three arguments."
1363 << true;
1364
1365 QTest::newRow(dataTag: "$$unique()")
1366 << "IN = foo bar foo baz\nVAR = $$unique(IN)"
1367 << "VAR = foo bar baz"
1368 << ""
1369 << true;
1370
1371 QTest::newRow(dataTag: "$$unique(): bad number of arguments")
1372 << "VAR = $$unique(1, 2)"
1373 << "VAR ="
1374 << "##:1: unique(var) requires one argument."
1375 << true;
1376
1377 QTest::newRow(dataTag: "$$sorted()")
1378 << "IN = one two three\nVAR = $$sorted(IN)"
1379 << "VAR = one three two"
1380 << ""
1381 << true;
1382
1383 QTest::newRow(dataTag: "$$sorted(): bad number of arguments")
1384 << "VAR = $$sorted(1, 2)"
1385 << "VAR ="
1386 << "##:1: sorted(var) requires one argument."
1387 << true;
1388
1389 QTest::newRow(dataTag: "$$reverse()")
1390 << "IN = one two three\nVAR = $$reverse(IN)"
1391 << "VAR = three two one"
1392 << ""
1393 << true;
1394
1395 QTest::newRow(dataTag: "$$reverse(): bad number of arguments")
1396 << "VAR = $$reverse(1, 2)"
1397 << "VAR ="
1398 << "##:1: reverse(var) requires one argument."
1399 << true;
1400
1401 QTest::newRow(dataTag: "$$quote()")
1402 << "VAR = $$quote(foo bar, 'foo bar')"
1403 << "VAR = 'foo bar' 'foo bar'"
1404 << ""
1405 << true;
1406
1407 // FIXME: \n and \r go untested, because there is no way to get them into the
1408 // expected result. And if there was one, this function would be unnecessary.
1409 // In other news, the behavior of backslash escaping makes no sense.
1410 QTest::newRow(dataTag: "$$escape_expand()")
1411 << "VAR = $$escape_expand(foo\\\\ttab\\\\\\\\slash\\\\invalid, verbatim)"
1412 << "VAR = 'foo\ttab\\\\\\\\slash\\\\invalid' verbatim"
1413 << ""
1414 << true;
1415
1416 QTest::newRow(dataTag: "$$upper()")
1417 << "VAR = $$upper(kEwL, STuff)"
1418 << "VAR = KEWL STUFF"
1419 << ""
1420 << true;
1421
1422 QTest::newRow(dataTag: "$$lower()")
1423 << "VAR = $$lower(kEwL, STuff)"
1424 << "VAR = kewl stuff"
1425 << ""
1426 << true;
1427
1428 QTest::newRow(dataTag: "$$title()")
1429 << "VAR = $$title(kEwL, STuff)"
1430 << "VAR = Kewl Stuff"
1431 << ""
1432 << true;
1433
1434 QTest::newRow(dataTag: "$$re_escape()")
1435 << "VAR = $$re_escape(one, hey.*you[funny]+people)"
1436 << "VAR = one hey\\\\.\\\\*you\\\\[funny\\\\]\\\\+people"
1437 << ""
1438 << true;
1439
1440 QTest::newRow(dataTag: "$$val_escape()")
1441 << "IN = easy \"less easy\" sca$${LITERAL_HASH}ry"
1442 " crazy$$escape_expand(\\\\t\\\\r\\\\n)"
1443 " $$escape_expand(\\\\t)stuff \\'no\\\"way\\\\here\n"
1444 "VAR = $$val_escape(IN)"
1445 << "VAR = easy '\\\"less easy\\\"' sca\\$\\${LITERAL_HASH}ry"
1446 " crazy\\$\\$escape_expand(\\\\\\\\t\\\\\\\\r\\\\\\\\n)"
1447 " \\$\\$escape_expand(\\\\\\\\t)stuff \\\\\\'no\\\\\\\"way\\\\\\\\here"
1448 << ""
1449 << true;
1450
1451 QTest::newRow(dataTag: "$$val_escape(): bad number of arguments")
1452 << "VAR = $$val_escape(1, 2)"
1453 << "VAR ="
1454 << "##:1: val_escape(var) requires one argument."
1455 << true;
1456
1457 QTest::newRow(dataTag: "$$files(): non-recursive")
1458 << "VAR = $$files(" + qindir + "/files/file*.txt)"
1459 << "VAR = " + qindir + "/files/file1.txt "
1460 + qindir + "/files/file2.txt"
1461 << ""
1462 << true;
1463
1464 QTest::newRow(dataTag: "$$files(): recursive")
1465 << "VAR = $$files(" + qindir + "/files/file*.txt, true)"
1466 << "VAR = " + qindir + "/files/file1.txt "
1467 + qindir + "/files/file2.txt "
1468 + qindir + "/files/dir/file1.txt "
1469 + qindir + "/files/dir/file2.txt"
1470 << ""
1471 << true;
1472
1473 QTest::newRow(dataTag: "$$files(): bad number of arguments")
1474 << "VAR = $$files(1, 2, 3)"
1475 << "VAR ="
1476 << "##:1: files(pattern, [recursive=false]) requires one or two arguments."
1477 << true;
1478
1479#if 0
1480 // FIXME: no emulated input layer
1481 QTest::newRow("$$prompt()")
1482 << "VAR = $$prompt(que)"
1483 << "VAR = whatever"
1484 << "Project PROMPT: que? "
1485 << true;
1486#endif
1487
1488 QTest::newRow(dataTag: "$$replace()")
1489 << "IN = foo 'bar baz'\nVAR = $$replace(IN, \\\\bba, hello)"
1490 << "VAR = foo 'hellor helloz'"
1491 << ""
1492 << true;
1493
1494 QTest::newRow(dataTag: "$$replace(): bad number of arguments")
1495 << "VAR = $$replace(1, 2) \\\n$$replace(1, 2, 3, 4)"
1496 << "VAR ="
1497 << "##:1: replace(var, before, after) requires three arguments.\n"
1498 "##:2: replace(var, before, after) requires three arguments."
1499 << true;
1500
1501 QTest::newRow(dataTag: "$$sort_depends()")
1502 << "foo.depends = bar baz\n"
1503 "bar.depends = baz bak duck\n"
1504 "baz.depends = bak\n"
1505 "bak.depends = duck\n"
1506 "VAR = $$sort_depends($$list(baz foo duck bar))"
1507 << "VAR = foo bar baz duck"
1508 << ""
1509 << true;
1510
1511 QTest::newRow(dataTag: "$$resolve_depends(): basic")
1512 << "foo.depends = bar baz\n"
1513 "bar.depends = baz bak duck\n"
1514 "baz.depends = bak\n"
1515 "bak.depends = duck\n"
1516 "VAR = $$resolve_depends($$list(baz foo duck bar))"
1517 << "VAR = foo bar baz bak duck"
1518 << ""
1519 << true;
1520
1521 QTest::newRow(dataTag: "$$resolve_depends(): prefix and multiple suffixes")
1522 << "MOD.foo.dep = bar baz\n"
1523 "MOD.bar.dep = baz bak\n"
1524 "MOD.bar.priv_dep = duck\n"
1525 "MOD.baz.dep = bak\n"
1526 "MOD.bak.dep = duck\n"
1527 "VAR = $$resolve_depends($$list(baz foo duck bar), MOD., .dep .priv_dep)"
1528 << "VAR = foo bar baz bak duck"
1529 << ""
1530 << true;
1531
1532 QTest::newRow(dataTag: "$$resolve_depends(): priorities: b first")
1533 << "MOD.a.depends =\n"
1534 "MOD.b.depends =\n"
1535 "MOD.b.priority = 1\n"
1536 "MOD.c.depends = a b\n"
1537 "VAR = $$resolve_depends($$list(c), MOD.)"
1538 << "VAR = c b a"
1539 << ""
1540 << true;
1541
1542 QTest::newRow(dataTag: "$$resolve_depends(): priorities: a first")
1543 << "MOD.a.depends =\n"
1544 "MOD.a.priority = 1\n"
1545 "MOD.b.depends =\n"
1546 "MOD.b.priority = 0\n"
1547 "MOD.c.depends = a b\n"
1548 "VAR = $$resolve_depends($$list(c), MOD.)"
1549 << "VAR = c a b"
1550 << ""
1551 << true;
1552
1553 QTest::newRow(dataTag: "$$resolve_depends(): priorities: custom suffix")
1554 << "MOD.a.depends =\n"
1555 "MOD.a.prrt = 1\n"
1556 "MOD.b.depends =\n"
1557 "MOD.b.prrt = 0\n"
1558 "MOD.c.depends = a b\n"
1559 "VAR = $$resolve_depends($$list(c), MOD., .depends, .prrt)"
1560 << "VAR = c a b"
1561 << ""
1562 << true;
1563
1564 QTest::newRow(dataTag: "$$resolve_depends(): bad number of arguments")
1565 << "VAR = $$resolve_depends(1, 2, 3, 4, 5)"
1566 << "VAR ="
1567 << "##:1: resolve_depends(var, [prefix, [suffixes, [prio-suffix]]]) requires one to four arguments."
1568 << true;
1569
1570 QTest::newRow(dataTag: "$$enumerate_vars()")
1571 << "V1 = foo\nV2 = bar\nVAR = $$enumerate_vars()\n"
1572 "count(VAR, 2, >=):contains(VAR, V1):contains(VAR, V2): OK = 1"
1573 << "OK = 1"
1574 << ""
1575 << true;
1576
1577 QTest::newRow(dataTag: "$$shadowed(): bare")
1578 << "VAR = $$shadowed(test.txt)"
1579 << "VAR = " + QMakeEvaluator::quoteValue(val: ProString(m_outdir + "/test.txt"))
1580 << ""
1581 << true;
1582
1583 QTest::newRow(dataTag: "$$shadowed(): subdir")
1584 << "VAR = $$shadowed(" + qindir + "/sub/test.txt)"
1585 << "VAR = " + QMakeEvaluator::quoteValue(val: ProString(m_outdir + "/sub/test.txt"))
1586 << ""
1587 << true;
1588
1589 QTest::newRow(dataTag: "$$shadowed(): outside source dir")
1590 << "VAR = $$shadowed(/some/random/path)"
1591 << "VAR ="
1592 << ""
1593 << true;
1594
1595 QTest::newRow(dataTag: "$$shadowed(): bad number of arguments")
1596 << "VAR = $$shadowed(1, 2)"
1597 << "VAR ="
1598 << "##:1: shadowed(path) requires one argument."
1599 << true;
1600
1601 QTest::newRow(dataTag: "$$absolute_path(): relative file")
1602 << "VAR = $$absolute_path(dir/file.ext)"
1603 << "VAR = " + qindir + "/dir/file.ext"
1604 << ""
1605 << true;
1606
1607 QTest::newRow(dataTag: "$$absolute_path(): relative file & relative path")
1608 << "VAR = $$absolute_path(dir/file.ext, some/where)"
1609 << "VAR = " + qindir + "/some/where/dir/file.ext"
1610 << ""
1611 << true;
1612
1613 QTest::newRow(dataTag: "$$absolute_path(): file & path")
1614 << "VAR = $$absolute_path(dir/file.ext, " EVAL_DRIVE "/root/sub)"
1615 << "VAR = " EVAL_DRIVE "/root/sub/dir/file.ext"
1616 << ""
1617 << true;
1618
1619#ifdef Q_OS_WIN
1620 QTest::newRow("$$absolute_path(): driveless file & absolute path")
1621 << "VAR = $$absolute_path(/root/sub/dir/file.ext, " EVAL_DRIVE "/other)"
1622 << "VAR = " EVAL_DRIVE "/root/sub/dir/file.ext"
1623 << ""
1624 << true;
1625#endif
1626
1627 QTest::newRow(dataTag: "$$absolute_path(): absolute file & path")
1628 << "VAR = $$absolute_path(" EVAL_DRIVE "/root/sub/dir/file.ext, " EVAL_DRIVE "/other)"
1629 << "VAR = " EVAL_DRIVE "/root/sub/dir/file.ext"
1630 << ""
1631 << true;
1632
1633 QTest::newRow(dataTag: "$$absolute_path(): empty file & path")
1634 << "VAR = $$absolute_path('', " EVAL_DRIVE "/root/sub)"
1635 << "VAR = " EVAL_DRIVE "/root/sub"
1636 << ""
1637 << true;
1638
1639 QTest::newRow(dataTag: "$$absolute_path(): bad number of arguments")
1640 << "VAR = $$absolute_path(1, 2, 3)"
1641 << "VAR ="
1642 << "##:1: absolute_path(path, [base]) requires one or two arguments."
1643 << true;
1644
1645 QTest::newRow(dataTag: "$$relative_path(): relative file")
1646 << "VAR = $$relative_path(dir/file.ext)"
1647 << "VAR = dir/file.ext"
1648 << ""
1649 << true;
1650
1651 QTest::newRow(dataTag: "$$relative_path(): relative file & relative path")
1652 << "VAR = $$relative_path(dir/file.ext, some/where)"
1653 << "VAR = dir/file.ext"
1654 << ""
1655 << true;
1656
1657 QTest::newRow(dataTag: "$$relative_path(): relative file to empty")
1658 << "VAR = $$relative_path(dir/..)"
1659 << "VAR = ."
1660 << ""
1661 << true;
1662
1663#ifdef Q_OS_WIN
1664 QTest::newRow("$$relative_path(): driveless file & absolute path")
1665 << "VAR = $$relative_path(/root/sub/dir/file.ext, " EVAL_DRIVE "/root/sub)"
1666 << "VAR = dir/file.ext"
1667 << ""
1668 << true;
1669#endif
1670
1671 QTest::newRow(dataTag: "$$relative_path(): absolute file & path")
1672 << "VAR = $$relative_path(" EVAL_DRIVE "/root/sub/dir/file.ext, " EVAL_DRIVE "/root/sub)"
1673 << "VAR = dir/file.ext"
1674 << ""
1675 << true;
1676
1677 QTest::newRow(dataTag: "$$relative_path(): empty file & path")
1678 << "VAR = $$relative_path('', " EVAL_DRIVE "/root/sub)"
1679 << "VAR = ."
1680 << ""
1681 << true;
1682
1683 QTest::newRow(dataTag: "$$relative_path(): bad number of arguments")
1684 << "VAR = $$relative_path(1, 2, 3)"
1685 << "VAR ="
1686 << "##:1: relative_path(path, [base]) requires one or two arguments."
1687 << true;
1688
1689 QTest::newRow(dataTag: "$$clean_path()")
1690#ifdef Q_OS_WIN // This is actually kinda stupid.
1691 << "VAR = $$clean_path(foo//bar\\\\../baz/)"
1692#else
1693 << "VAR = $$clean_path(foo//bar/../baz/)"
1694#endif
1695 << "VAR = foo/baz"
1696 << ""
1697 << true;
1698
1699 QTest::newRow(dataTag: "$$clean_path(): bad number of arguments")
1700 << "VAR = $$clean_path(1, 2)"
1701 << "VAR ="
1702 << "##:1: clean_path(path) requires one argument."
1703 << true;
1704
1705 QTest::newRow(dataTag: "$$system_path()")
1706 << "VAR = $$system_path(foo/bar\\\\baz)"
1707#ifdef Q_OS_WIN
1708 << "VAR = foo\\\\bar\\\\baz"
1709#else
1710 << "VAR = foo/bar/baz"
1711#endif
1712 << ""
1713 << true;
1714
1715 QTest::newRow(dataTag: "$$system_path(): bad number of arguments")
1716 << "VAR = $$system_path(1, 2)"
1717 << "VAR ="
1718 << "##:1: system_path(path) requires one argument."
1719 << true;
1720
1721 // This is is effectively $$system_path() in this test, as we load no specs
1722 QTest::newRow(dataTag: "$$shell_path()")
1723 << "VAR = $$shell_path(foo/bar\\\\baz)"
1724#ifdef Q_OS_WIN
1725 << "VAR = foo\\\\bar\\\\baz"
1726#else
1727 << "VAR = foo/bar/baz"
1728#endif
1729 << ""
1730 << true;
1731
1732 QTest::newRow(dataTag: "$$shell_path(): bad number of arguments")
1733 << "VAR = $$shell_path(1, 2)"
1734 << "VAR ="
1735 << "##:1: shell_path(path) requires one argument."
1736 << true;
1737
1738 // The quoteArgs() test exercises this more thoroughly
1739 QTest::newRow(dataTag: "$$system_quote()")
1740 << "IN = \nVAR = $$system_quote(\"some nasty & ugly\\\" path & thing\\\\\")"
1741#ifdef Q_OS_WIN
1742 << "VAR = \"\\\"some nasty & ugly\\\\\\\" path ^& thing\\\\\\\\^\\\"\""
1743#else
1744 << "VAR = \"'some nasty & ugly\\\" path & thing\\\\'\""
1745#endif
1746 << ""
1747 << true;
1748
1749 QTest::newRow(dataTag: "$$system_quote(): bad number of arguments")
1750 << "VAR = $$system_quote(1, 2)"
1751 << "VAR ="
1752 << "##:1: system_quote(arg) requires one argument."
1753 << true;
1754
1755 // This is is effectively $$system_path() in this test, as we load no specs
1756 QTest::newRow(dataTag: "$$shell_quote()")
1757 << "IN = \nVAR = $$shell_quote(\"some nasty & ugly\\\" path & thing\\\\\")"
1758#ifdef Q_OS_WIN
1759 << "VAR = \"\\\"some nasty & ugly\\\\\\\" path ^& thing\\\\\\\\^\\\"\""
1760#else
1761 << "VAR = \"'some nasty & ugly\\\" path & thing\\\\'\""
1762#endif
1763 << ""
1764 << true;
1765
1766 QTest::newRow(dataTag: "$$shell_quote(): bad number of arguments")
1767 << "VAR = $$shell_quote(1, 2)"
1768 << "VAR ="
1769 << "##:1: shell_quote(arg) requires one argument."
1770 << true;
1771
1772 QTest::newRow(dataTag: "$$getenv()")
1773 << "VAR = $$getenv(E1)"
1774 << "VAR = 'env var'"
1775 << ""
1776 << true;
1777
1778 QTest::newRow(dataTag: "$$getenv(): bad number of arguments")
1779 << "VAR = $$getenv(1, 2)"
1780 << "VAR ="
1781 << "##:1: getenv(arg) requires one argument."
1782 << true;
1783}
1784
1785void tst_qmakelib::addTestFunctions(const QString &qindir)
1786{
1787 QTest::newRow(dataTag: "defined(): found replace")
1788 << "defineReplace(func) {}\ndefined(func): OK = 1"
1789 << "OK = 1"
1790 << ""
1791 << true;
1792
1793 QTest::newRow(dataTag: "defined(): found test")
1794 << "defineTest(func) {}\ndefined(func): OK = 1"
1795 << "OK = 1"
1796 << ""
1797 << true;
1798
1799 QTest::newRow(dataTag: "defined(): not found")
1800 << "defined(func): OK = 1"
1801 << "OK = UNDEF"
1802 << ""
1803 << true;
1804
1805 QTest::newRow(dataTag: "defined(replace): found")
1806 << "defineReplace(func) {}\ndefined(func, replace): OK = 1"
1807 << "OK = 1"
1808 << ""
1809 << true;
1810
1811 QTest::newRow(dataTag: "defined(replace): not found")
1812 << "defineTest(func) {}\ndefined(func, replace): OK = 1"
1813 << "OK = UNDEF"
1814 << ""
1815 << true;
1816
1817 QTest::newRow(dataTag: "defined(test): found")
1818 << "defineTest(func) {}\ndefined(func, test): OK = 1"
1819 << "OK = 1"
1820 << ""
1821 << true;
1822
1823 QTest::newRow(dataTag: "defined(test): not found")
1824 << "defineReplace(func) {}\ndefined(func, test): OK = 1"
1825 << "OK = UNDEF"
1826 << ""
1827 << true;
1828
1829 QTest::newRow(dataTag: "defined(var): found")
1830 << "VAR = 1\ndefined(VAR, var): OK = 1"
1831 << "OK = 1"
1832 << ""
1833 << true;
1834
1835 QTest::newRow(dataTag: "defined(var): not found")
1836 << "defined(VAR, var): OK = 1"
1837 << "OK = UNDEF"
1838 << ""
1839 << true;
1840
1841 QTest::newRow(dataTag: "defined(): invalid type")
1842 << "defined(VAR, nope): OK = 1"
1843 << "OK = UNDEF"
1844 << "##:1: defined(function, type): unexpected type [nope]."
1845 << true;
1846
1847 QTest::newRow(dataTag: "defined(): bad number of arguments")
1848 << "defined(1, 2, 3): OK = 1"
1849 << "OK = UNDEF"
1850 << "##:1: defined(object, [\"test\"|\"replace\"|\"var\"]) requires one or two arguments."
1851 << true;
1852
1853 QTest::newRow(dataTag: "export()")
1854 << "defineTest(func) {\n"
1855 "VAR1 += different\nexport(VAR1)\n"
1856 "unset(VAR2)\nexport(VAR2): OK = 1\nexport(OK)\n"
1857 "VAR3 = new var\nexport(VAR3)\n"
1858 "}\n"
1859 "VAR1 = entirely\nVAR2 = set\nfunc()"
1860 << "OK = 1\nVAR1 = entirely different\nVAR2 =\nVAR3 = new var"
1861 << ""
1862 << true;
1863
1864 QTest::newRow(dataTag: "export(): bad number of arguments")
1865 << "export(1, 2): OK = 1"
1866 << "OK = UNDEF"
1867 << "##:1: export(var) requires one argument."
1868 << true;
1869
1870 QTest::newRow(dataTag: "infile(): found")
1871 << "infile(" + qindir + "/fromfile/infile.prx, DEFINES): OK = 1"
1872 << "OK = 1"
1873 << ""
1874 << true;
1875
1876 QTest::newRow(dataTag: "infile(): not found")
1877 << "infile(" + qindir + "/fromfile/infile.prx, INCLUDES): OK = 1"
1878 << "OK = UNDEF"
1879 << ""
1880 << true;
1881
1882 QTest::newRow(dataTag: "infile(plain): found")
1883 << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, QT_DLL): OK = 1"
1884 << "OK = 1"
1885 << ""
1886 << true;
1887
1888 QTest::newRow(dataTag: "infile(plain): not found")
1889 << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, NOPE): OK = 1"
1890 << "OK = UNDEF"
1891 << ""
1892 << true;
1893
1894 QTest::newRow(dataTag: "infile(regex): found")
1895 << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, QT_.*): OK = 1"
1896 << "OK = 1"
1897 << ""
1898 << true;
1899
1900 QTest::newRow(dataTag: "infile(regex): not found")
1901 << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, NO.*): OK = 1"
1902 << "OK = UNDEF"
1903 << ""
1904 << true;
1905
1906 // The early return is debatable, esp. as it's inconsistent with $$fromfile()
1907 QTest::newRow(dataTag: "infile(): bad file")
1908 << "infile(" + qindir + "/fromfile/badfile.prx, DEFINES): OK = 1\nOKE = 1"
1909 << "OK = UNDEF\nOKE = UNDEF"
1910 << "Project ERROR: fail!"
1911 << false;
1912
1913 QTest::newRow(dataTag: "infile(): bad number of arguments")
1914 << "infile(1): OK = 1\ninfile(1, 2, 3, 4): OK = 1"
1915 << "OK = UNDEF"
1916 << "##:1: infile(file, var, [values]) requires two or three arguments.\n"
1917 "##:2: infile(file, var, [values]) requires two or three arguments."
1918 << true;
1919
1920 QTest::newRow(dataTag: "requires()")
1921 << "requires(true, false, isEmpty(FOO), !isEmpty(BAR), true|false, true:false)"
1922 << "QMAKE_FAILED_REQUIREMENTS = false !isEmpty(BAR) true:false"
1923 << ""
1924 << true;
1925
1926 // The sparator semantics are *very* questionable.
1927 // The return value semantics are rather questionable.
1928 QTest::newRow(dataTag: "eval()")
1929 << "eval(FOO = one, two$$escape_expand(\\\\n)BAR = blah$$escape_expand(\\\\n)error(fail)$$escape_expand(\\\\n)BAZ = nope)"
1930 << "FOO = one two\nBAR = blah\nBAZ = UNDEF"
1931 << "Project ERROR: fail"
1932 << true;
1933
1934 QTest::newRow(dataTag: "if(): true")
1935 << "if(false|true): OK = 1"
1936 << "OK = 1"
1937 << ""
1938 << true;
1939
1940 QTest::newRow(dataTag: "if(): true (space)")
1941 << "if(false| true): OK = 1"
1942 << "OK = 1"
1943 << ""
1944 << true;
1945
1946 QTest::newRow(dataTag: "if(): true (spaces)")
1947 << "if( false | true ): OK = 1"
1948 << "OK = 1"
1949 << ""
1950 << true;
1951
1952 QTest::newRow(dataTag: "if(): false")
1953 << "if(false:true): OK = 1"
1954 << "OK = UNDEF"
1955 << ""
1956 << true;
1957
1958 QTest::newRow(dataTag: "if(): false (space)")
1959 << "if(false: true): OK = 1"
1960 << "OK = UNDEF"
1961 << ""
1962 << true;
1963
1964 QTest::newRow(dataTag: "if(): false (spaces)")
1965 << "if( false : true ): OK = 1"
1966 << "OK = UNDEF"
1967 << ""
1968 << true;
1969
1970 QTest::newRow(dataTag: "if(): bad number of arguments")
1971 << "if(1, 2): OK = 1"
1972 << "OK = UNDEF"
1973 << "##:1: if(condition) requires one argument."
1974 << true;
1975
1976 QTest::newRow(dataTag: "CONFIG(simple): true")
1977 << "CONFIG = debug release\nCONFIG(debug): OK = 1"
1978 << "OK = 1"
1979 << ""
1980 << true;
1981
1982 QTest::newRow(dataTag: "CONFIG(simple): false")
1983 << "CONFIG = debug release\nCONFIG(nope): OK = 1"
1984 << "OK = UNDEF"
1985 << ""
1986 << true;
1987
1988 QTest::newRow(dataTag: "CONFIG(alt): true")
1989 << "CONFIG = debug release\nCONFIG(release, debug|release): OK = 1"
1990 << "OK = 1"
1991 << ""
1992 << true;
1993
1994 QTest::newRow(dataTag: "CONFIG(alt): false (presence)")
1995 << "CONFIG = not here\nCONFIG(debug, debug|release): OK = 1"
1996 << "OK = UNDEF"
1997 << ""
1998 << true;
1999
2000 QTest::newRow(dataTag: "CONFIG(alt): false (order)")
2001 << "CONFIG = debug release\nCONFIG(debug, debug|release): OK = 1"
2002 << "OK = UNDEF"
2003 << ""
2004 << true;
2005
2006 QTest::newRow(dataTag: "CONFIG(): bad number of arguments")
2007 << "CONFIG(1, 2, 3): OK = 1"
2008 << "OK = UNDEF"
2009 << "##:1: CONFIG(config, [mutuals]) requires one or two arguments."
2010 << true;
2011
2012 QTest::newRow(dataTag: "contains(simple plain): true")
2013 << "VAR = one two three\ncontains(VAR, two): OK = 1"
2014 << "OK = 1"
2015 << ""
2016 << true;
2017
2018 QTest::newRow(dataTag: "contains(simple plain): false")
2019 << "VAR = one two three\ncontains(VAR, four): OK = 1"
2020 << "OK = UNDEF"
2021 << ""
2022 << true;
2023
2024 QTest::newRow(dataTag: "contains(simple regex): true")
2025 << "VAR = one two three\ncontains(VAR, tw.*): OK = 1"
2026 << "OK = 1"
2027 << ""
2028 << true;
2029
2030 QTest::newRow(dataTag: "contains(simple regex): false")
2031 << "VAR = one two three\ncontains(VAR, fo.*): OK = 1"
2032 << "OK = UNDEF"
2033 << ""
2034 << true;
2035
2036 QTest::newRow(dataTag: "contains(alt plain): true")
2037 << "VAR = one two three\ncontains(VAR, three, two|three): OK = 1"
2038 << "OK = 1"
2039 << ""
2040 << true;
2041
2042 QTest::newRow(dataTag: "contains(alt plain): false (presence)")
2043 << "VAR = one four five\ncontains(VAR, three, two|three): OK = 1"
2044 << "OK = UNDEF"
2045 << ""
2046 << true;
2047
2048 QTest::newRow(dataTag: "contains(alt plain): false (order)")
2049 << "VAR = one two three\ncontains(VAR, two, two|three): OK = 1"
2050 << "OK = UNDEF"
2051 << ""
2052 << true;
2053
2054 QTest::newRow(dataTag: "contains(alt regex): true")
2055 << "VAR = one two three\ncontains(VAR, th.*, two|three): OK = 1"
2056 << "OK = 1"
2057 << ""
2058 << true;
2059
2060 QTest::newRow(dataTag: "contains(alt regex): false (presence)")
2061 << "VAR = one four five\ncontains(VAR, th.*, two|three): OK = 1"
2062 << "OK = UNDEF"
2063 << ""
2064 << true;
2065
2066 QTest::newRow(dataTag: "contains(alt regex): false (order)")
2067 << "VAR = one two three\ncontains(VAR, tw.*, two|three): OK = 1"
2068 << "OK = UNDEF"
2069 << ""
2070 << true;
2071
2072 QTest::newRow(dataTag: "contains(): bad number of arguments")
2073 << "contains(1): OK = 1\ncontains(1, 2, 3, 4): OK = 1"
2074 << "OK = UNDEF"
2075 << "##:1: contains(var, val, [mutuals]) requires two or three arguments.\n"
2076 "##:2: contains(var, val, [mutuals]) requires two or three arguments."
2077 << true;
2078
2079 QTest::newRow(dataTag: "count(): true")
2080 << "VAR = one two three\ncount(VAR, 3): OK = 1"
2081 << "OK = 1"
2082 << ""
2083 << true;
2084
2085 QTest::newRow(dataTag: "count(): false")
2086 << "VAR = one two three\ncount(VAR, 4): OK = 1"
2087 << "OK = UNDEF"
2088 << ""
2089 << true;
2090
2091 QTest::newRow(dataTag: "count(operators): true")
2092 << "VAR = one two three\n"
2093 "count(VAR, 3, equals): OKE1 = 1\n"
2094 "count(VAR, 3, isEqual): OKE2 = 1\n"
2095 "count(VAR, 3, =): OKE3 = 1\n"
2096 "count(VAR, 3, ==): OKE4 = 1\n"
2097 "count(VAR, 2, greaterThan): OKG1 = 1\n"
2098 "count(VAR, 2, >): OKG2 = 1\n"
2099 "count(VAR, 2, >=): OKGE = 1\n"
2100 "count(VAR, 4, lessThan): OKL1 = 1\n"
2101 "count(VAR, 4, <): OKL2 = 1\n"
2102 "count(VAR, 4, <=): OKLE = 1\n"
2103 << "OKE1 = 1\nOKE2 = 1\nOKE3 = 1\nOKE4 = 1\n"
2104 "OKG1 = 1\nOKG2 = 1\nOKGE = 1\n"
2105 "OKL1 = 1\nOKL2 = 1\nOKLE = 1"
2106 << ""
2107 << true;
2108
2109 QTest::newRow(dataTag: "count(operators): false")
2110 << "VAR = one two three\n"
2111 "count(VAR, 4, equals): OKE1 = 1\n"
2112 "count(VAR, 4, isEqual): OKE2 = 1\n"
2113 "count(VAR, 4, =): OKE3 = 1\n"
2114 "count(VAR, 4, ==): OKE4 = 1\n"
2115 "count(VAR, 3, greaterThan): OKG1 = 1\n"
2116 "count(VAR, 3, >): OKG2 = 1\n"
2117 "count(VAR, 4, >=): OKGE = 1\n"
2118 "count(VAR, 3, lessThan): OKL1 = 1\n"
2119 "count(VAR, 3, <): OKL2 = 1\n"
2120 "count(VAR, 2, <=): OKLE = 1\n"
2121 << "OKE1 = UNDEF\nOKE2 = UNDEF\nOKE3 = UNDEF\nOKE4 = UNDEF\n"
2122 "OKG1 = UNDEF\nOKG2 = UNDEF\nOKGE = UNDEF\n"
2123 "OKL1 = UNDEF\nOKL2 = UNDEF\nOKLE = UNDEF"
2124 << ""
2125 << true;
2126
2127 QTest::newRow(dataTag: "count(): bad operator")
2128 << "VAR = one two three\ncount(VAR, 2, !!!): OK = 1"
2129 << "OK = UNDEF"
2130 << "##:2: Unexpected modifier to count(!!!)."
2131 << true;
2132
2133 QTest::newRow(dataTag: "count(): bad number of arguments")
2134 << "count(1): OK = 1\ncount(1, 2, 3, 4): OK = 1"
2135 << "OK = UNDEF"
2136 << "##:1: count(var, count, [op=operator]) requires two or three arguments.\n"
2137 "##:2: count(var, count, [op=operator]) requires two or three arguments."
2138 << true;
2139
2140 QTest::newRow(dataTag: "greaterThan(int): true")
2141 << "VAR = 20\ngreaterThan(VAR, 3): OK = 1"
2142 << "OK = 1"
2143 << ""
2144 << true;
2145
2146 QTest::newRow(dataTag: "greaterThan(int): false")
2147 << "VAR = 3\ngreaterThan(VAR, 20): OK = 1"
2148 << "OK = UNDEF"
2149 << ""
2150 << true;
2151
2152 QTest::newRow(dataTag: "greaterThan(string): true")
2153 << "VAR = foo 3\ngreaterThan(VAR, foo 20): OK = 1"
2154 << "OK = 1"
2155 << ""
2156 << true;
2157
2158 QTest::newRow(dataTag: "greaterThan(string): false")
2159 << "VAR = foo 20\ngreaterThan(VAR, foo 3): OK = 1"
2160 << "OK = UNDEF"
2161 << ""
2162 << true;
2163
2164 QTest::newRow(dataTag: "greaterThan(): bad number of arguments")
2165 << "greaterThan(1): OK = 1\ngreaterThan(1, 2, 3): OK = 1"
2166 << "OK = UNDEF"
2167 << "##:1: greaterThan(var, val) requires two arguments.\n"
2168 "##:2: greaterThan(var, val) requires two arguments."
2169 << true;
2170
2171 QTest::newRow(dataTag: "lessThan(int): true")
2172 << "VAR = 3\nlessThan(VAR, 20): OK = 1"
2173 << "OK = 1"
2174 << ""
2175 << true;
2176
2177 QTest::newRow(dataTag: "lessThan(int): false")
2178 << "VAR = 20\nlessThan(VAR, 3): OK = 1"
2179 << "OK = UNDEF"
2180 << ""
2181 << true;
2182
2183 QTest::newRow(dataTag: "lessThan(string): true")
2184 << "VAR = foo 20\nlessThan(VAR, foo 3): OK = 1"
2185 << "OK = 1"
2186 << ""
2187 << true;
2188
2189 QTest::newRow(dataTag: "lessThan(string): false")
2190 << "VAR = foo 3\nlessThan(VAR, foo 20): OK = 1"
2191 << "OK = UNDEF"
2192 << ""
2193 << true;
2194
2195 QTest::newRow(dataTag: "lessThan(): bad number of arguments")
2196 << "lessThan(1): OK = 1\nlessThan(1, 2, 3): OK = 1"
2197 << "OK = UNDEF"
2198 << "##:1: lessThan(var, val) requires two arguments.\n"
2199 "##:2: lessThan(var, val) requires two arguments."
2200 << true;
2201
2202 QTest::newRow(dataTag: "equals(): true")
2203 << "VAR = foo\nequals(VAR, foo): OK = 1"
2204 << "OK = 1"
2205 << ""
2206 << true;
2207
2208 QTest::newRow(dataTag: "equals(): false")
2209 << "VAR = foo\nequals(VAR, bar): OK = 1"
2210 << "OK = UNDEF"
2211 << ""
2212 << true;
2213
2214 QTest::newRow(dataTag: "equals(): bad number of arguments")
2215 << "equals(1): OK = 1\nequals(1, 2, 3): OK = 1"
2216 << "OK = UNDEF"
2217 << "##:1: equals(var, val) requires two arguments.\n"
2218 "##:2: equals(var, val) requires two arguments."
2219 << true;
2220
2221 // That's just an alias, so don't test much.
2222 QTest::newRow(dataTag: "isEqual(): true")
2223 << "VAR = foo\nisEqual(VAR, foo): OK = 1"
2224 << "OK = 1"
2225 << ""
2226 << true;
2227
2228 QTest::newRow(dataTag: "versionAtLeast(): true")
2229 << "VAR = 1.2.3\nversionAtLeast(VAR, 1.2.3): OK = 1"
2230 << "OK = 1"
2231 << ""
2232 << true;
2233
2234 QTest::newRow(dataTag: "versionAtLeast(): false")
2235 << "VAR = 1.2.2\nversionAtLeast(VAR, 1.2.3): OK = 1"
2236 << "OK = UNDEF"
2237 << ""
2238 << true;
2239
2240 QTest::newRow(dataTag: "versionAtLeast(): bad number of arguments")
2241 << "versionAtLeast(1): OK = 1\nversionAtLeast(1, 2, 3): OK = 1"
2242 << "OK = UNDEF"
2243 << "##:1: versionAtLeast(var, version) requires two arguments.\n"
2244 "##:2: versionAtLeast(var, version) requires two arguments."
2245 << true;
2246
2247 QTest::newRow(dataTag: "versionAtMost(): true")
2248 << "VAR = 1.2.3\nversionAtMost(VAR, 1.2.3): OK = 1"
2249 << "OK = 1"
2250 << ""
2251 << true;
2252
2253 QTest::newRow(dataTag: "versionAtMost(): false")
2254 << "VAR = 1.2.3\nversionAtMost(VAR, 1.2.2): OK = 1"
2255 << "OK = UNDEF"
2256 << ""
2257 << true;
2258
2259 QTest::newRow(dataTag: "versionAtMost(): bad number of arguments")
2260 << "versionAtMost(1): OK = 1\nversionAtMost(1, 2, 3): OK = 1"
2261 << "OK = UNDEF"
2262 << "##:1: versionAtMost(var, version) requires two arguments.\n"
2263 "##:2: versionAtMost(var, version) requires two arguments."
2264 << true;
2265
2266 QTest::newRow(dataTag: "clear(): top-level")
2267 << "VAR = there\nclear(VAR): OK = 1"
2268 << "OK = 1\nVAR ="
2269 << ""
2270 << true;
2271
2272 QTest::newRow(dataTag: "clear(): scoped")
2273 << "defineTest(func) {\n"
2274 "clear(VAR): OK = 1\nexport(OK)\n"
2275 "equals(VAR, \"\"): OKE = 1\nexport(OKE)\n"
2276 "}\n"
2277 "VAR = there\nfunc()"
2278 << "OK = 1\nOKE = 1"
2279 << ""
2280 << true;
2281
2282 QTest::newRow(dataTag: "clear(): absent")
2283 << "clear(VAR): OK = 1"
2284 << "OK = UNDEF\nVAR = UNDEF"
2285 << ""
2286 << true;
2287
2288 QTest::newRow(dataTag: "clear(): bad number of arguments")
2289 << "clear(1, 2): OK = 1"
2290 << "OK = UNDEF"
2291 << "##:1: clear(var) requires one argument."
2292 << true;
2293
2294 QTest::newRow(dataTag: "unset(): top-level")
2295 << "VAR = there\nunset(VAR): OK = 1"
2296 << "OK = 1\nVAR = UNDEF"
2297 << ""
2298 << true;
2299
2300 QTest::newRow(dataTag: "unset(): scoped")
2301 << "defineTest(func) {\n"
2302 "unset(VAR): OK = 1\nexport(OK)\n"
2303 "!defined(VAR, var): OKE = 1\nexport(OKE)\n"
2304 "}\n"
2305 "VAR = there\nfunc()"
2306 << "OK = 1\nOKE = 1"
2307 << ""
2308 << true;
2309
2310 QTest::newRow(dataTag: "unset(): absent")
2311 << "unset(VAR): OK = 1"
2312 << "OK = UNDEF\nVAR = UNDEF"
2313 << ""
2314 << true;
2315
2316 QTest::newRow(dataTag: "unset(): bad number of arguments")
2317 << "unset(1, 2): OK = 1"
2318 << "OK = UNDEF"
2319 << "##:1: unset(var) requires one argument."
2320 << true;
2321
2322 // This function does not follow the established naming pattern.
2323 QTest::newRow(dataTag: "parseJson()")
2324 << "jsontext = \\\n"
2325 " \"{\"\\\n"
2326 " \" \\\"array\\\" : [\\\"arrayItem1\\\", \\\"arrayItem2\\\", \\\"arrayItem3\\\"],\"\\\n"
2327 " \" \\\"object\\\" : { \\\"key1\\\" : \\\"objectValue1\\\", \\\"key2\\\" : \\\"objectValue2\\\" },\"\\\n"
2328 " \" \\\"string\\\" : \\\"test string\\\",\"\\\n"
2329 " \" \\\"number\\\" : 999,\"\\\n"
2330 " \" \\\"true\\\" : true,\"\\\n"
2331 " \" \\\"false\\\" :false,\"\"\\\n"
2332 " \" \\\"null\\\" : null\"\"\\\n"
2333 " \"}\"\n"
2334 "parseJson(jsontext, json): OK = 1"
2335 << "OK = 1\n"
2336 "json._KEYS_ = array false null number object string true\n"
2337 // array
2338 "json.array._KEYS_ = 0 1 2\n"
2339 "json.array.0 = arrayItem1\n"
2340 "json.array.1 = arrayItem2\n"
2341 "json.array.2 = arrayItem3\n"
2342 // object
2343 "json.object._KEYS_ = key1 key2\n"
2344 "json.object.key1 = objectValue1\n"
2345 "json.object.key1 = objectValue1\n"
2346 // value types
2347 "json.string = 'test string'\n"
2348 "json.number = 999\n"
2349 "json.true = true\n"
2350 "json.false = false\n"
2351 "json.null = UNDEF"
2352 << ""
2353 << true;
2354
2355 QTest::newRow(dataTag: "parseJson(): bad input")
2356 << "jsontext = not good\n"
2357 "parseJson(jsontext, json): OK = 1"
2358 << "OK = UNDEF"
2359 << "##:2: Error parsing JSON at 1:1: illegal value"
2360 << true;
2361
2362 QTest::newRow(dataTag: "parseJson(): bad number of arguments")
2363 << "parseJson(1): OK = 1\nparseJson(1, 2, 3): OK = 1"
2364 << "OK = UNDEF"
2365 << "##:1: parseJson(var, into) requires two arguments.\n"
2366 "##:2: parseJson(var, into) requires two arguments."
2367 << true;
2368
2369 QTest::newRow(dataTag: "include()")
2370 << "include(include/inc.pri): OK = 1\nfunc()"
2371 << "OK = 1\nVAR = val\n.VAR = nope"
2372 << "Project MESSAGE: say hi!"
2373 << true;
2374
2375 QTest::newRow(dataTag: "include(): fail")
2376 << "include(include/nope.pri): OK = 1"
2377 << "OK = UNDEF"
2378 << "Cannot read " + m_indir + "/include/nope.pri: No such file or directory"
2379 << true;
2380
2381 QTest::newRow(dataTag: "include(): silent fail")
2382 << "include(include/nope.pri, , true): OK = 1"
2383 << "OK = 1"
2384 << ""
2385 << true;
2386
2387 QTest::newRow(dataTag: "include(into)")
2388 << "SUB.MISS = 1\ninclude(include/inc.pri, SUB): OK = 1"
2389 << "OK = 1\nSUB.VAR = val\nSUB..VAR = UNDEF\nSUB.MISS = UNDEF\n"
2390 // As a side effect, we test some things that need full project setup
2391 "SUB.MATCH = 1\nSUB.QMAKESPEC = " + qindir + "/mkspecs/fake-g++"
2392 << ""
2393 << true;
2394
2395 QTest::newRow(dataTag: "include(): bad number of arguments")
2396 << "include(1, 2, 3, 4): OK = 1"
2397 << "OK = UNDEF"
2398 << "##:1: include(file, [into, [silent]]) requires one to three arguments."
2399 << true;
2400
2401 QTest::newRow(dataTag: "load()")
2402 << "load(testfeat): OK = 1"
2403 << "OK = 1\nVAR = foo bar"
2404 << ""
2405 << true;
2406
2407 QTest::newRow(dataTag: "load(): fail")
2408 << "load(no_such_feature): OK = 1"
2409 << "OK = UNDEF"
2410 << "##:1: Cannot find feature no_such_feature"
2411 << true;
2412
2413 QTest::newRow(dataTag: "load(): silent fail")
2414 << "load(no_such_feature, true): OK = 1"
2415 << "OK = 1"
2416 << ""
2417 << true;
2418
2419 QTest::newRow(dataTag: "load(): bad number of arguments")
2420 << "load(1, 2, 3): OK = 1"
2421 << "OK = UNDEF"
2422 << "##:1: load(feature, [ignore_errors=false]) requires one or two arguments."
2423 << true;
2424
2425 QTest::newRow(dataTag: "discard_from()")
2426 << "HERE = 1\nPLUS = one\n"
2427 "defineTest(tfunc) {}\ndefineReplace(rfunc) {}\n"
2428 "include(include/inc.pri)\n"
2429 "contains(QMAKE_INTERNAL_INCLUDED_FILES, .*/include/inc\\\\.pri): PRE = 1\n"
2430 "discard_from(include/inc.pri): OK = 1\n"
2431 "!contains(QMAKE_INTERNAL_INCLUDED_FILES, .*/include/inc\\\\.pri): POST = 1\n"
2432 "defined(tfunc, test): TDEF = 1\ndefined(rfunc, replace): RDEF = 1\n"
2433 "defined(func, test): DTDEF = 1\ndefined(func, replace): DRDEF = 1\n"
2434 << "PRE = 1\nPOST = 1\nOK = 1\nHERE = 1\nPLUS = one\nVAR = UNDEF\n"
2435 "TDEF = 1\nRDEF = 1\nDTDEF = UNDEF\nDRDEF = UNDEF"
2436 << ""
2437 << true;
2438
2439 QTest::newRow(dataTag: "discard_from(): bad number of arguments")
2440 << "discard_from(1, 2): OK = 1"
2441 << "OK = UNDEF"
2442 << "##:1: discard_from(file) requires one argument."
2443 << true;
2444
2445 // We don't test debug() and log(), because they print directly to stderr.
2446
2447 QTest::newRow(dataTag: "message()")
2448 << "message('Hello, World!'): OK = 1\nOKE = 1"
2449 << "OK = 1\nOKE = 1"
2450 << "Project MESSAGE: Hello, World!"
2451 << true;
2452
2453 // Don't test that for warning() and error(), as it's the same code path.
2454 QTest::newRow(dataTag: "message(): bad number of arguments")
2455 << "message(1, 2): OK = 1"
2456 << "OK = UNDEF"
2457 << "##:1: message(message) requires one argument."
2458 << true;
2459
2460 QTest::newRow(dataTag: "warning()")
2461 << "warning('World, be warned!'): OK = 1\nOKE = 1"
2462 << "OK = 1\nOKE = 1"
2463 << "Project WARNING: World, be warned!"
2464 << true;
2465
2466 QTest::newRow(dataTag: "error(message)")
2467 << "error('World, you FAIL!'): OK = 1\nOKE = 1"
2468 << "OK = UNDEF\nOKE = UNDEF"
2469 << "Project ERROR: World, you FAIL!"
2470 << false;
2471
2472 QTest::newRow(dataTag: "error(empty)")
2473 << "error(): OK = 1\nOKE = 1"
2474 << "OK = UNDEF\nOKE = UNDEF"
2475 << ""
2476 << false;
2477
2478 QTest::newRow(dataTag: "if(error())")
2479 << "if(error(\\'World, you FAIL!\\')): OK = 1\nOKE = 1"
2480 << "OK = UNDEF\nOKE = UNDEF"
2481 << "Project ERROR: World, you FAIL!"
2482 << false;
2483
2484 QTest::newRow(dataTag: "system()")
2485 << "system('"
2486#ifdef Q_OS_WIN
2487 "cd"
2488#else
2489 "pwd"
2490#endif
2491 "> '" + QMakeEvaluator::quoteValue(val: ProString(QDir::toNativeSeparators(
2492 pathName: m_outdir + "/system_out.txt"))) + "): OK = 1\n"
2493 "DIR = $$cat(" + QMakeEvaluator::quoteValue(val: ProString(
2494 m_outdir + "/system_out.txt")) + ")"
2495 << "OK = 1\nDIR = " + QMakeEvaluator::quoteValue(val: ProString(QDir::toNativeSeparators(pathName: m_indir)))
2496 << ""
2497 << true;
2498
2499 QTest::newRow(dataTag: "system(): fail")
2500#ifdef Q_OS_WIN
2501 << "system(no_such_cmd 2> NUL): OK = 1"
2502#else
2503 << "system(no_such_cmd 2> /dev/null): OK = 1"
2504#endif
2505 << "OK = UNDEF"
2506 << ""
2507 << true;
2508
2509 QTest::newRow(dataTag: "system(): bad number of arguments")
2510 << "system(1, 2): OK = 1"
2511 << "OK = UNDEF"
2512 << "##:1: system(exec) requires one argument."
2513 << true;
2514
2515 QTest::newRow(dataTag: "isEmpty(): true (empty)")
2516 << "VAR =\nisEmpty(VAR): OK = 1"
2517 << "OK = 1"
2518 << ""
2519 << true;
2520
2521 QTest::newRow(dataTag: "isEmpty(): true (undef)")
2522 << "isEmpty(VAR): OK = 1"
2523 << "OK = 1"
2524 << ""
2525 << true;
2526
2527 QTest::newRow(dataTag: "isEmpty(): false")
2528 << "VAR = val\nisEmpty(VAR): OK = 1"
2529 << "OK = UNDEF"
2530 << ""
2531 << true;
2532
2533 QTest::newRow(dataTag: "isEmpty(): bad number of arguments")
2534 << "isEmpty(1, 2): OK = 1"
2535 << "OK = UNDEF"
2536 << "##:1: isEmpty(var) requires one argument."
2537 << true;
2538
2539 QTest::newRow(dataTag: "exists(plain): true")
2540 << "exists(files/file1.txt): OK = 1"
2541 << "OK = 1"
2542 << ""
2543 << true;
2544
2545 QTest::newRow(dataTag: "exists(plain): false")
2546 << "exists(files/not_there.txt): OK = 1"
2547 << "OK = UNDEF"
2548 << ""
2549 << true;
2550
2551 QTest::newRow(dataTag: "exists(wildcard): true")
2552 << "exists(files/fil*.txt): OK = 1"
2553 << "OK = 1"
2554 << ""
2555 << true;
2556
2557 QTest::newRow(dataTag: "exists(wildcard): false")
2558 << "exists(files/not_th*.txt): OK = 1"
2559 << "OK = UNDEF"
2560 << ""
2561 << true;
2562
2563 QTest::newRow(dataTag: "exists(): bad number of arguments")
2564 << "exists(1, 2): OK = 1"
2565 << "OK = UNDEF"
2566 << "##:1: exists(file) requires one argument."
2567 << true;
2568
2569 QString wpath = QMakeEvaluator::quoteValue(val: ProString(m_outdir + "/outdir/written.txt"));
2570 QTest::newRow(dataTag: "write_file(): create")
2571 << "VAR = 'this is text' 'yet again'\n"
2572 "write_file(" + wpath + ", VAR): OK = 1\n"
2573 "OUT = $$cat(" + wpath + ", lines)"
2574 << "OK = 1\nOUT = 'this is text' 'yet again'"
2575 << ""
2576 << true;
2577
2578 QTest::newRow(dataTag: "write_file(): truncate")
2579 << "VAR = 'other content'\n"
2580 "write_file(" + wpath + ", VAR): OK = 1\n"
2581 "OUT = $$cat(" + wpath + ", lines)"
2582 << "OK = 1\nOUT = 'other content'"
2583 << ""
2584 << true;
2585
2586 // FIXME: This also tests that 'exe' is accepted, but does not test whether it actually works.
2587 QTest::newRow(dataTag: "write_file(): append")
2588 << "VAR = 'one more line'\n"
2589 "write_file(" + wpath + ", VAR, append exe): OK = 1\n"
2590 "OUT = $$cat(" + wpath + ", lines)"
2591 << "OK = 1\nOUT = 'other content' 'one more line'"
2592 << ""
2593 << true;
2594
2595 QString vpath = QMakeEvaluator::quoteValue(val: ProString(m_outdir));
2596 QTest::newRow(dataTag: "write_file(): fail")
2597 << "write_file(" + vpath + "): OK = 1"
2598 << "OK = UNDEF"
2599#ifdef Q_OS_WIN
2600 << "##:1: Cannot write file " + QDir::toNativeSeparators(m_outdir) + ": Access is denied."
2601#else
2602 << "##:1: Cannot write file " + m_outdir + ": Is a directory"
2603#endif
2604 << true;
2605
2606 QTest::newRow(dataTag: "write_file(): bad number of arguments")
2607 << "write_file(1, 2, 3, 4): OK = 1"
2608 << "OK = UNDEF"
2609 << "##:1: write_file(name, [content var, [append] [exe]]) requires one to three arguments."
2610 << true;
2611
2612 QTest::newRow(dataTag: "write_file(): invalid flag")
2613 << "write_file(file, VAR, fail): OK = 1"
2614 << "OK = UNDEF"
2615 << "##:1: write_file(): invalid flag fail."
2616 << true;
2617
2618 // FIXME: This doesn't test whether it actually works.
2619 QTest::newRow(dataTag: "touch()")
2620 << "touch(" + wpath + ", files/other.txt): OK = 1"
2621 << "OK = 1"
2622 << ""
2623 << true;
2624
2625 QTest::newRow(dataTag: "touch(): missing target")
2626 << "touch(" EVAL_DRIVE "/does/not/exist, files/other.txt): OK = 1"
2627 << "OK = UNDEF"
2628#ifdef Q_OS_WIN
2629 << "##:1: Cannot open " EVAL_DRIVE "/does/not/exist: The system cannot find the path specified."
2630#else
2631 << "##:1: Cannot touch /does/not/exist: No such file or directory."
2632#endif
2633 << true;
2634
2635 QTest::newRow(dataTag: "touch(): missing reference")
2636 << "touch(" + wpath + ", " EVAL_DRIVE "/does/not/exist): OK = 1"
2637 << "OK = UNDEF"
2638#ifdef Q_OS_WIN
2639 << "##:1: Cannot open reference file " EVAL_DRIVE "/does/not/exist: The system cannot find the path specified."
2640#else
2641 << "##:1: Cannot stat() reference file /does/not/exist: No such file or directory."
2642#endif
2643 << true;
2644
2645 QTest::newRow(dataTag: "touch(): bad number of arguments")
2646 << "touch(1): OK = 1\ntouch(1, 2, 3): OK = 1"
2647 << "OK = UNDEF"
2648 << "##:1: touch(file, reffile) requires two arguments.\n"
2649 "##:2: touch(file, reffile) requires two arguments."
2650 << true;
2651
2652 QString apath = QMakeEvaluator::quoteValue(val: ProString(m_outdir + "/a/path"));
2653 QTest::newRow(dataTag: "mkpath()")
2654 << "mkpath(" + apath + "): OK = 1\n"
2655 "exists(" + apath + "): OKE = 1"
2656 << "OK = 1\nOKE = 1"
2657 << ""
2658 << true;
2659
2660 QString bpath = QMakeEvaluator::quoteValue(val: ProString(m_outdir + "/fail_me"));
2661 QTest::newRow(dataTag: "mkpath(): fail")
2662 << "write_file(" + bpath + ")|error(FAIL)\n"
2663 "mkpath(" + bpath + "): OK = 1"
2664 << "OK = UNDEF"
2665 << "##:2: Cannot create directory " + QDir::toNativeSeparators(pathName: m_outdir + "/fail_me") + '.'
2666 << true;
2667
2668 QTest::newRow(dataTag: "mkpath(): bad number of arguments")
2669 << "mkpath(1, 2): OK = 1"
2670 << "OK = UNDEF"
2671 << "##:1: mkpath(path) requires one argument."
2672 << true;
2673
2674#if 0
2675 // FIXME ... insanity lies ahead
2676 QTest::newRow("cache()")
2677 << ""
2678 << ""
2679 << ""
2680 << true;
2681#endif
2682}
2683
2684void tst_qmakelib::proEval_data()
2685{
2686 QTest::addColumn<QString>(name: "in");
2687 QTest::addColumn<QString>(name: "out");
2688 QTest::addColumn<QString>(name: "msgs");
2689 QTest::addColumn<bool>(name: "ok");
2690
2691 QTest::newRow(dataTag: "empty")
2692 << ""
2693 << "VAR = UNDEF"
2694 << ""
2695 << true;
2696
2697 addAssignments();
2698 addExpansions(); // Variable, etc. expansions on RHS
2699 addControlStructs(); // Conditions, loops, custom functions
2700
2701 QString qindir = QMakeEvaluator::quoteValue(val: ProString(m_indir));
2702 addReplaceFunctions(qindir); // Built-in replace functions
2703 addTestFunctions(qindir); // Built-in test functions
2704
2705 // Some compound tests that verify compatibility with odd Qt 4 edge cases
2706
2707 QTest::newRow(dataTag: "empty (leading)")
2708 << "defineTest(myMsg) { message(\"$$1\") }\n"
2709 "XMPL = /this/is/a/test\n"
2710 "message(split: $$split(XMPL, /))\n"
2711 "message(split joined:$$split(XMPL, /))\n"
2712 "message(\"split quoted: $$split(XMPL, /)\")\n"
2713 "myMsg(my split: $$split(XMPL, /) :post)\n"
2714 "myMsg(my split joined:$$split(XMPL, /):post)\n"
2715 "myMsg(\"my split quoted: $$split(XMPL, /) post\")\n"
2716 "OUT = word $$split(XMPL, /) done\n"
2717 "message(\"assign split separate: $$OUT\")\n"
2718 "OUT = word:$$split(XMPL, /):done\n"
2719 "message(\"assign split joined: $$OUT\")\n"
2720 "OUT = \"word $$split(XMPL, /) done\"\n"
2721 "message(\"assign split quoted: $$OUT\")\n"
2722 << ""
2723 << "Project MESSAGE: split: this is a test\n"
2724 "Project MESSAGE: split joined: this is a test\n"
2725 "Project MESSAGE: split quoted: this is a test\n"
2726 "Project MESSAGE: my split: this is a test :post\n"
2727 "Project MESSAGE: my split joined: this is a test:post\n"
2728 "Project MESSAGE: my split quoted: this is a test post\n"
2729 "Project MESSAGE: assign split separate: word this is a test done\n"
2730 "Project MESSAGE: assign split joined: word: this is a test:done\n"
2731 "Project MESSAGE: assign split quoted: word this is a test done"
2732 << true;
2733
2734 QTest::newRow(dataTag: "empty (multiple)")
2735 << "defineTest(myMsg) { message(\"$$1\") }\n"
2736 "XMPL = //this///is/a/////test\n"
2737 "message(split: $$split(XMPL, /) :post)\n"
2738 "message(split joined:$$split(XMPL, /):post)\n"
2739 "message(\"split quoted: $$split(XMPL, /) post\")\n"
2740 "myMsg(my split: $$split(XMPL, /) :post)\n"
2741 "myMsg(my split joined:$$split(XMPL, /):post)\n"
2742 "myMsg(\"my split quoted: $$split(XMPL, /) post\")\n"
2743 "OUT = word $$split(XMPL, /) done\n"
2744 "message(\"assign split separate: $$OUT\")\n"
2745 "OUT = word:$$split(XMPL, /):done\n"
2746 "message(\"assign split joined: $$OUT\")\n"
2747 "OUT = \"word $$split(XMPL, /) done\"\n"
2748 "message(\"assign split quoted: $$OUT\")\n"
2749 << ""
2750 << "Project MESSAGE: split: this is a test :post\n"
2751 "Project MESSAGE: split joined: this is a test:post\n"
2752 "Project MESSAGE: split quoted: this is a test post\n"
2753 "Project MESSAGE: my split: this is a test :post\n"
2754 "Project MESSAGE: my split joined: this is a test:post\n"
2755 "Project MESSAGE: my split quoted: this is a test post\n"
2756 "Project MESSAGE: assign split separate: word this is a test done\n"
2757 "Project MESSAGE: assign split joined: word: this is a test:done\n"
2758 "Project MESSAGE: assign split quoted: word this is a test done"
2759 << true;
2760
2761 // Raw data leak with empty file name. Verify with Valgrind or asan.
2762 QTest::newRow(dataTag: "QTBUG-54550")
2763 << "FULL = " EVAL_DRIVE "/there/is\n"
2764 "VAR = $$absolute_path(, $$FULL/nothing/here/really)"
2765 << "VAR = " EVAL_DRIVE "/there/is/nothing/here/really"
2766 << ""
2767 << true;
2768}
2769
2770static QString formatValue(const ProStringList &vals)
2771{
2772 QString ret;
2773
2774 foreach (const ProString &str, vals) {
2775 ret += QLatin1Char(' ');
2776 ret += QMakeEvaluator::quoteValue(val: str);
2777 }
2778 return ret;
2779}
2780
2781static void skipNoise(const ushort *&tokPtr)
2782{
2783 forever {
2784 ushort tok = *tokPtr;
2785 if (tok != TokLine)
2786 break;
2787 tokPtr += 2;
2788 }
2789}
2790
2791static bool compareState(QMakeEvaluator *eval, ProFile *out)
2792{
2793 bool ret = true;
2794 const ushort *tokPtr = out->tokPtr();
2795 forever {
2796 skipNoise(tokPtr);
2797 ushort tok = *tokPtr++;
2798 if (!tok)
2799 break;
2800 if (tok != TokHashLiteral) {
2801 qWarning(msg: "Expected output is malformed: not variable%s",
2802 qPrintable(QMakeParser::formatProBlock(out->items())));
2803 return false;
2804 }
2805 const ProKey &var = out->getHashStr(tPtr&: tokPtr);
2806 tok = *tokPtr++;
2807 if (tok != TokAssign) {
2808 qWarning(msg: "Expected output is malformed: not assignment%s",
2809 qPrintable(QMakeParser::formatProBlock(out->items())));
2810 return false;
2811 }
2812 ProStringList value;
2813 value.reserve(asize: *tokPtr++);
2814 forever {
2815 skipNoise(tokPtr);
2816 tok = *tokPtr++;
2817 if (tok == TokValueTerminator)
2818 break;
2819 if (tok != (TokLiteral | TokNewStr)) {
2820 qWarning(msg: "Expected output is malformed: not literal%s",
2821 qPrintable(QMakeParser::formatProBlock(out->items())));
2822 return false;
2823 }
2824 value << out->getStr(tPtr&: tokPtr);
2825 }
2826 ProValueMap::Iterator it;
2827 ProValueMap *vmap = eval->findValues(variableName: var, it: &it);
2828 if (value.length() == 1 && value.at(i: 0) == "UNDEF") {
2829 if (vmap) {
2830 qWarning(msg: "Value of %s is incorrect.\n Actual:%s\nExpected: <UNDEFINED>",
2831 qPrintable(var.toQString()),
2832 qPrintable(formatValue(*it)));
2833 ret = false;
2834 }
2835 } else {
2836 if (!vmap) {
2837 qWarning(msg: "Value of %s is incorrect.\n Actual: <UNDEFINED>\nExpected:%s",
2838 qPrintable(var.toQString()),
2839 qPrintable(formatValue(value)));
2840 ret = false;
2841 } else if (*it != value) {
2842 qWarning(msg: "Value of %s is incorrect.\n Actual:%s\nExpected:%s",
2843 qPrintable(var.toQString()),
2844 qPrintable(formatValue(*it)), qPrintable(formatValue(value)));
2845 ret = false;
2846 }
2847 }
2848 }
2849 return ret;
2850}
2851
2852void tst_qmakelib::proEval()
2853{
2854 QFETCH(QString, in);
2855 QFETCH(QString, out);
2856 QFETCH(QString, msgs);
2857 QFETCH(bool, ok);
2858
2859 QString infile = m_indir + "/test.pro";
2860 bool verified = true;
2861 QMakeTestHandler handler;
2862 handler.setExpectedMessages(msgs.replace(before: "##:", after: infile + ':').split(sep: '\n', behavior: Qt::SkipEmptyParts));
2863 QMakeVfs vfs;
2864 ProFileCache cache;
2865 QMakeParser parser(&cache, &vfs, &handler);
2866 QMakeGlobals globals;
2867 globals.do_cache = false;
2868 globals.xqmakespec = "fake-g++";
2869 globals.environment = m_env;
2870 globals.setProperties(m_prop);
2871 globals.setDirectories(input_dir: m_indir, output_dir: m_outdir);
2872 ProFile *outPro = parser.parsedProBlock(contents: QStringRef(&out), id: 0, name: "out", line: 1, grammar: QMakeParser::FullGrammar);
2873 if (!outPro->isOk()) {
2874 qWarning(msg: "Expected output is malformed");
2875 verified = false;
2876 }
2877 ProFile *pro = parser.parsedProBlock(contents: QStringRef(&in), id: 0, name: infile, line: 1, grammar: QMakeParser::FullGrammar);
2878 QMakeEvaluator visitor(&globals, &parser, &vfs, &handler);
2879 visitor.setOutputDir(m_outdir);
2880#ifdef Q_OS_WIN
2881 visitor.m_dirSep = ProString("\\");
2882#else
2883 visitor.m_dirSep = ProString("/");
2884#endif
2885 QMakeEvaluator::VisitReturn ret
2886 = visitor.visitProFile(pro, type: QMakeHandler::EvalAuxFile, flags: QMakeEvaluator::LoadProOnly);
2887 if (handler.printedMessages()) {
2888 qWarning(msg: "Got unexpected message(s)");
2889 verified = false;
2890 }
2891 QStringList missingMsgs = handler.expectedMessages();
2892 if (!missingMsgs.isEmpty()) {
2893 foreach (const QString &msg, missingMsgs)
2894 qWarning(msg: "Missing message: %s", qPrintable(msg));
2895 verified = false;
2896 }
2897 if ((ret == QMakeEvaluator::ReturnTrue) != ok) {
2898 static const char * const lbl[] = { "failure", "success" };
2899 qWarning(msg: "Expected %s, got %s", lbl[int(ok)], lbl[1 - int(ok)]);
2900 verified = false;
2901 }
2902 if (!compareState(eval: &visitor, out: outPro))
2903 verified = false;
2904 pro->deref();
2905 outPro->deref();
2906 QVERIFY(verified);
2907}
2908

source code of qtbase/tests/auto/tools/qmakelib/evaltest.cpp