cmd/tests: Additional CALL tests.
[wine/multimedia.git] / programs / cmd / tests / test_builtins.cmd
blob04d8fdda5a9536b00ce58605355182df21628463
1 echo Tests for cmd's builtin commands
3 @echo on
4 echo ------------ Testing 'echo' [ON] --------------
5 echo word
6 echo 'singlequotedword'
7 echo "doublequotedword"
8 @echo at-echoed-word
9 echo "/?"
10 echo.
11 echo .
12 echo.word
13 echo .word
14 echo:
15 echo :
16 echo:word
17 echo :word
18 echo word@space@
19 echo word@space@@space@
21 @echo off
22 echo ------------ Testing 'echo' [OFF] --------------
23 echo word
24 echo 'singlequotedword'
25 echo "doublequotedword"
26 @echo at-echoed-word
27 echo "/?"
28 echo.
29 echo .
30 echo.word
31 echo .word
32 echo:
33 echo :
34 echo:word
35 echo :word
36 echo word@space@
37 echo word@space@@space@
39 echo ------------ Testing redirection operators --------------
40 mkdir foobar & cd foobar
41 echo ...stdout redirection
42 echo foo>foo
43 type foo
44 echo foo 1> foo
45 type foo
46 echo foo1> foo
47 type foo
48 echo foo11> foo
49 type foo
50 echo foo12> foo
51 type foo
52 echo ...stdout appending
53 echo foo>foo
54 echo foo >>foo
55 type foo
56 del foo
57 echo foob >> foo
58 type foo
59 echo fooc 1>>foo
60 type foo
61 echo food1>>foo
62 type foo
63 echo food2>>foo
64 type foo
65 del foo
66 echo food21>>foo
67 type foo
68 cd ..
69 rd /s/q foobar
71 echo ------------ Testing ^^ escape character --------------
72 rem Using something like "echo foo^" asks for an additional char after a "More?" prompt on the following line; it's not possible to currently test that non-interactively
73 echo ^hell^o, world
74 echo hell^o, world
75 echo hell^^o, world
76 echo hell^^^o, world
77 mkdir foobar
78 echo baz> foobar\baz
79 type foobar\baz
80 type foobar^\baz
81 rd /s/q foobar
82 echo foo ^| echo bar
83 echo foo ^& echo bar
84 call :setError 0
85 echo bak ^&& echo baz 2> nul
86 echo %ErrorLevel%
87 echo foo ^> foo
88 echo ^<> foo
89 type foo
90 del foo
91 set FOO=oof
92 echo ff^%FOO%
93 set FOO=bar ^| baz
94 set FOO
95 rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
96 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
97 echo %ErrorLevel%
98 call :setError 0
99 set FOO=bar ^^^| baz
100 set FOO
101 echo %FOO%
102 echo %ErrorLevel%
103 set FOO=
105 echo ------------ Testing 'set' --------------
106 call :setError 0
107 set FOOBAR 2> nul > nul
108 echo %ErrorLevel%
109 set FOOBAR = baz
110 echo %ErrorLevel%
111 echo %FOOBAR%FOOBAR not defined
112 echo %FOOBAR %
113 set FOOBAR 2> nul
114 set FOOBAR = baz2
115 echo %ErrorLevel%
116 echo %fOObAr %
117 set FOOBAR= bar
118 echo %ErrorLevel%
119 echo %FOOBAR%
120 set FOO
121 set FOOBAR=
122 set FOOB
123 echo %FOOBAR%FOOBAR not defined
124 set FOOBAR =
125 set FOOBA 2> nul > nul
126 echo %ErrorLevel%
127 set FOO=bar
128 echo %FOO%
129 set FOO=foo
130 set BAR=bar
131 echo %FOO%%BAR%
132 set BAR=
133 set FOO=
134 set FOO=%FOO%
135 echo %FOO%FOO not defined
136 set BAZ%=bazbaz
137 set BA
138 echo %BAZ%%
139 set BAZ%=
140 echo set "FOO=bar" should not include the quotes in the variable value
141 set "FOO=bar"
142 echo %FOO%
143 set FOO=
145 echo ------------ Testing variable expansion --------------
146 call :setError 0
147 echo ~dp0 should be directory containing batch file
148 echo %~dp0
149 mkdir dummydir
150 cd dummydir
151 echo %~dp0
152 cd ..
153 rmdir dummydir
154 echo CD value %CD%
155 echo %%
156 echo P%
157 echo %P
158 echo %UNKNOWN%S
159 echo P%UNKNOWN%
160 echo P%UNKNOWN%S
161 echo %ERRORLEVEL
162 echo %ERRORLEVEL%
163 echo %ERRORLEVEL%%ERRORLEVEL%
164 echo %ERRORLEVEL%ERRORLEVEL%
165 echo %ERRORLEVEL%%
166 echo %ERRORLEVEL%%%
167 echo P%ERRORLEVEL%
168 echo %ERRORLEVEL%S
169 echo P%ERRORLEVEL%S
171 echo ------------ Testing conditional execution --------------
172 echo ...unconditional ^&
173 call :setError 123 & echo foo1
174 echo bar2 & echo foo2
175 mkdir foobar & cd foobar
176 echo > foobazbar
177 cd .. & rd /s/q foobar
178 if exist foobazbar (
179 echo foobar not deleted!
180 cd ..
181 rd /s/q foobar
182 ) else echo foobar deleted
183 echo ...on success conditional ^&^&
184 call :setError 456 && echo foo3 > foo3
185 if exist foo3 (
186 echo foo3 created
187 del foo3
188 ) else echo foo3 not created
189 echo bar4 && echo foo4
190 echo ...on failure conditional ^|^|
191 call :setError 789 || echo foo5
192 echo foo6 || echo bar6 > bar6
193 if exist bar6 (
194 echo bar6 created
195 del bar6
198 echo ------------ Testing type ------------
199 echo bar> foobaz
200 @echo on
201 type foobaz
202 echo ***
203 @echo off
204 type foobaz
205 echo ***
206 del foobaz
208 echo ------------ Testing NUL ------------
209 md foobar & cd foobar
210 rem NUL file (non) creation + case insensitivity
211 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
212 echo > bar
213 echo foo > NUL
214 dir /b /a-d
215 echo foo > nul
216 dir /b /a-d
217 echo foo > NuL
218 dir /b /a-d
219 del bar
220 rem NUL not special everywhere
221 call :setError 123
222 echo NUL> foo
223 if not exist foo (echo foo should have been created) else (
224 type foo
225 del foo
227 rem Empty file creation
228 copy nul foo > nul
229 if exist foo (
230 echo foo created
231 del foo
232 type foo
233 ) else (
234 echo ***
236 cd ..
237 rd foobar
239 echo ------------ Testing if/else --------------
240 echo if/else should work with blocks
241 if 0 == 0 (
242 echo if seems to work
243 ) else (
244 echo if seems to be broken
246 if 1 == 0 (
247 echo else seems to be broken
248 ) else (
249 echo else seems to work
251 if /c==/c (
252 echo if seems not to detect /c as parameter
253 ) else (
254 echo parameter detection seems to be broken
256 echo Testing case sensitivity with and without /i option
257 if bar==BAR echo if does not default to case sensitivity
258 if not bar==BAR echo if seems to default to case sensitivity
259 if /i foo==FOO echo if /i seems to work
260 if /i not foo==FOO echo if /i seems to be broken
261 if /I foo==FOO echo if /I seems to work
262 if /I not foo==FOO echo if /I seems to be broken
264 echo -----------Testing for -----------
265 echo ...plain FOR
266 for %%i in (A B C) do echo %%i
267 for %%i in (A B C) do echo %%I
268 for %%i in (A B C) do echo %%j
269 for %%i in (A B C) do call :forTestFun1 %%i
270 for %%i in (1,4,1) do echo %%i
271 for %%i in (A, B,C) do echo %%i
272 goto :endForTestFun1
273 :forTestFun1
274 echo %1
275 goto :eof
276 :endForTestFun1
277 echo ...imbricated FORs
278 for %%i in (X) do (
279 for %%j in (Y) do (
280 echo %%i %%j))
281 for %%i in (X) do (
282 for %%I in (Y) do (
283 echo %%i %%I))
284 for %%i in (A B) do (
285 for %%j in (C D) do (
286 echo %%i %%j))
287 for %%i in (A B) do (
288 for %%j in (C D) do (
289 call :forTestFun2 %%i %%j ))
290 goto :endForTestFun2
291 :forTestFun2
292 echo %1 %2
293 goto :eof
294 :endForTestFun2
295 mkdir foobar & cd foobar
296 mkdir foo
297 mkdir bar
298 mkdir baz
299 echo > bazbaz
300 echo ...basic wildcards
301 for %%i in (ba*) do echo %%i
302 echo ...for /d
303 for /d %%i in (baz foo bar) do echo %%i
304 rem FIXME for /d incorrectly parses when wildcards are used
305 rem for /d %%i in (bazb*) do echo %%i
306 rem FIXME can't test wildcard expansion here since it's listed in directory
307 rem order, and not in alphabetic order.
308 rem Proper testing would need a currently missing "sort" program implementation.
309 rem for /d %%i in (ba*) do echo %%i>> tmp
310 rem sort < tmp
311 rem del tmp
312 rem for /d %%i in (?a*) do echo %%i>> tmp
313 rem sort < tmp
314 rem del tmp
315 rem for /d %%i in (*) do echo %%i>> tmp
316 rem sort < tmp
317 rem del tmp
318 cd ..
319 rd /s/Q foobar
320 echo ...for /L
321 rem Some cases loop forever writing 0s, like e.g. (1,0,1), (1,a,3) or (a,b,c); those can't be tested here
322 for /L %%i in (1,2,0) do echo %%i
323 for /L %%i in (1,2,6) do echo %%i
324 for /l %%i in (1 ,2,6) do echo %%i
325 for /L %%i in (a,2,3) do echo %%i
326 for /L %%i in (1,2,-1) do echo %%i
327 for /L %%i in (-4,-1,-1) do echo %%i
328 for /L %%i in (1,-2,-2) do echo %%i
329 for /L %%i in (1,2,a) do echo %%i
330 echo ErrorLevel %ErrorLevel%
331 for /L %%i in (1,a,b) do echo %%i
332 echo ErrorLevel %ErrorLevel%
333 rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
334 rem for /L %%i in (a,2,b) do echo %%i
335 rem for /L %%i in (1,1,1) do echo %%i
336 rem for /L %%i in (1,-2,-1) do echo %%i
337 rem for /L %%i in (-1,-1,-1) do echo %%i
338 rem for /L %%i in (1,2, 3) do echo %%i
340 echo -----------Testing del /a-----------
341 del /f/q *.test > nul
342 echo r > r.test
343 attrib +r r.test
344 echo not-r > not-r.test
346 if not exist not-r.test echo not-r.test not found before delete, bad
347 del /a:-r *.test
348 if not exist not-r.test echo not-r.test not found after delete, good
350 if not exist r.test echo r.test not found before delete, bad
351 if exist r.test echo r.test found before delete, good
352 del /a:r *.test
353 if not exist r.test echo r.test not found after delete, good
354 if exist r.test echo r.test found after delete, bad
356 echo ------------ Testing del /q --------------
357 mkdir del_q_dir
358 cd del_q_dir
359 echo abc > file1
360 echo abc > file2.dat
361 rem If /q doesn't work, cmd will prompt and the test case should hang
362 del /q * > nul
363 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
364 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
365 cd ..
366 rmdir del_q_dir
368 echo ------------ Testing del /s --------------
369 mkdir "foo bar"
370 cd "foo bar"
371 echo hi > file1.dat
372 echo there > file2.dat
373 echo bub > file3.dat
374 echo bye > "file with spaces.dat"
375 cd ..
376 del /s file1.dat > nul
377 del file2.dat /s > nul
378 del "file3.dat" /s > nul
379 del "file with spaces.dat" /s > nul
380 cd "foo bar"
381 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
382 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
383 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
384 if exist "file with spaces.dat" del "file with spaces.dat"
385 cd ..
386 rmdir "foo bar"
388 echo ----------- Testing mkdir -----------
389 call :setError 0
390 rem md and mkdir are synonymous
391 mkdir foobar
392 echo %ErrorLevel%
393 rmdir foobar
394 md foobar
395 echo %ErrorLevel%
396 rmdir foobar
397 rem Creating an already existing directory/file must fail
398 mkdir foobar
399 md foobar
400 echo %ErrorLevel%
401 rmdir foobar
402 echo > foobar
403 mkdir foobar
404 echo %ErrorLevel%
405 del foobar
406 rem Multi-level path creation
407 mkdir foo
408 echo %ErrorLevel%
409 mkdir foo\bar\baz
410 echo %ErrorLevel%
411 cd foo
412 echo %ErrorLevel%
413 cd bar
414 echo %ErrorLevel%
415 cd baz
416 echo %ErrorLevel%
417 echo > ..\..\bar2
418 mkdir ..\..\..\foo\bar2
419 echo %ErrorLevel%
420 del ..\..\bar2
421 mkdir ..\..\..\foo\bar2
422 echo %ErrorLevel%
423 rmdir ..\..\..\foo\bar2
424 cd ..
425 rmdir baz
426 cd ..
427 rmdir bar
428 cd ..
429 rmdir foo
430 echo %ErrorLevel%
431 rem Trailing backslashes
432 mkdir foo\\\\
433 echo %ErrorLevel%
434 if exist foo (rmdir foo & echo dir created
435 ) else ( echo dir not created )
436 echo %ErrorLevel%
437 rem Invalid chars
438 mkdir ?
439 echo %ErrorLevel%
440 call :setError 0
441 mkdir ?\foo
442 echo %ErrorLevel%
443 call :setError 0
444 mkdir foo\?
445 echo %ErrorLevel%
446 if exist foo (rmdir foo & echo ok, foo created
447 ) else ( echo foo not created )
448 call :setError 0
449 mkdir foo\bar\?
450 echo %ErrorLevel%
451 call :setError 0
452 if not exist foo (
453 echo bad, foo not created
454 ) else (
455 cd foo
456 if exist bar (
457 echo ok, foo\bar created
458 rmdir bar
460 cd ..
461 rmdir foo
463 rem multiples directories at once
464 mkdir foobaz & cd foobaz
465 mkdir foo bar\baz foobar
466 if exist foo (echo foo created) else echo foo not created!
467 if exist bar (echo bar created) else echo bar not created!
468 if exist foobar (echo foobar created) else echo foobar not created!
469 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
470 cd ..
471 rd /s/q foobaz
473 echo ----------- Testing rmdir -----------
474 call :setError 0
475 rem rd and rmdir are synonymous
476 mkdir foobar
477 rmdir foobar
478 echo %ErrorLevel%
479 if not exist foobar echo dir removed
480 mkdir foobar
481 rd foobar
482 echo %ErrorLevel%
483 if not exist foobar echo dir removed
484 rem Removing non-existent directory
485 rmdir foobar
486 echo %ErrorLevel%
487 rem Removing single-level directories
488 echo > foo
489 rmdir foo
490 echo %ErrorLevel%
491 if exist foo echo file not removed
492 del foo
493 mkdir foo
494 echo > foo\bar
495 rmdir foo
496 echo %ErrorLevel%
497 if exist foo echo non-empty dir not removed
498 del foo\bar
499 mkdir foo\bar
500 rmdir foo
501 echo %ErrorLevel%
502 if exist foo echo non-empty dir not removed
503 rmdir foo\bar
504 rmdir foo
505 rem Recursive rmdir
506 mkdir foo\bar\baz
507 rmdir /s /Q foo
508 if not exist foo (
509 echo recursive rmdir succeeded
510 ) else (
511 rd foo\bar\baz
512 rd foo\bar
513 rd foo
515 mkdir foo\bar\baz
516 echo foo > foo\bar\brol
517 rmdir /s /Q foo
518 if not exist foo (
519 echo recursive rmdir succeeded
520 ) else (
521 rd foo\bar\baz
522 del foo\bar\brol
523 rd foo\bar
524 rd foo
526 rem multiples directories at once
527 mkdir foobaz & cd foobaz
528 mkdir foo
529 mkdir bar\baz
530 mkdir foobar
531 rd /s/q foo bar foobar
532 if not exist foo (echo foo removed) else echo foo not removed!
533 if not exist bar (echo bar removed) else echo bar not removed!
534 if not exist foobar (echo foobar removed) else echo foobar not removed!
535 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
536 cd ..
537 rd /s/q foobaz
539 echo ------------ Testing CALL --------------
540 mkdir foobar & cd foobar
541 rem External script
542 echo echo foo %%1> foo.cmd
543 call foo
544 call foo.cmd 8
545 echo echo %%1 %%2 > foo.cmd
546 call foo.cmd foo
547 call foo.cmd foo bar
548 call foo.cmd foo ""
549 call foo.cmd "" bar
550 call foo.cmd foo ''
551 call foo.cmd '' bar
552 del foo.cmd
553 rem Internal routines
554 call :testRoutine :testRoutine
555 goto :endTestRoutine
556 :testRoutine
557 echo bar %1
558 goto :eof
559 :endTestRoutine
561 call :testRoutineArgs foo
562 call :testRoutineArgs foo bar
563 call :testRoutineArgs foo ""
564 call :testRoutineArgs "" bar
565 call :testRoutineArgs foo ''
566 call :testRoutineArgs '' bar
567 goto :endTestRoutineArgs
568 :testRoutineArgs
569 echo %1 %2
570 goto :eof
571 :endTestRoutineArgs
573 rem Should work for builtins...
574 call mkdir foo
575 echo %ErrorLevel%
576 if exist foo (echo foo created) else echo foo should exist!
577 rmdir foo
578 set FOOBAZ_VAR=foobaz
579 call echo Should expand %FOOBAZ_VAR%
580 set FOOBAZ_VAR=
581 echo>batfile
582 call dir /b
583 echo>robinfile
584 if 1==1 call del batfile
585 dir /b
586 if exist batfile echo batfile shouldn't exist
587 rem ... but not for 'if' or 'for'
588 call if 1==1 echo bar 2> nul
589 echo %ErrorLevel%
590 call :setError 0
591 call for %%i in (foo bar baz) do echo %%i 2> nul
592 echo %ErrorLevel%
593 rem First look for programs in the path before trying a builtin
594 echo echo non-builtin dir> dir.cmd
595 call dir /b
596 cd ..
597 rd /s/q foobar
599 echo -----------Testing Errorlevel-----------
600 rem WARNING: Do *not* add tests using ErrorLevel after this section
601 should_not_exist 2> nul > nul
602 echo %ErrorLevel%
603 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
604 rem See http://www.robvanderwoude.com/exit.php
605 call :setError 1
606 echo %ErrorLevel%
607 if errorlevel 2 echo errorlevel too high, bad
608 if errorlevel 1 echo errorlevel just right, good
609 call :setError 0
610 echo abc%ErrorLevel%def
611 if errorlevel 1 echo errorlevel nonzero, bad
612 if not errorlevel 1 echo errorlevel zero, good
613 rem Now verify that setting a real variable hides its magic variable
614 set errorlevel=7
615 echo %ErrorLevel% should be 7
616 if errorlevel 7 echo setting var worked too well, bad
617 call :setError 3
618 echo %ErrorLevel% should still be 7
620 echo -----------Testing GOTO-----------
621 if a==a goto dest1
622 :dest1
623 echo goto with no leading space worked
624 if b==b goto dest2
625 :dest2
626 echo goto with a leading space worked
627 if c==c goto dest3
628 :dest3
629 echo goto with a leading tab worked
630 if d==d goto dest4
631 :dest4@space@
632 echo goto with a following space worked
634 echo -----------Done, jumping to EOF-----------
635 goto :eof
636 rem Subroutine to set errorlevel and return
637 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
638 :setError
639 exit /B %1
640 rem This line runs under cmd in windows NT 4, but not in more modern versions.