1 echo Tests for cmd's builtin commands
4 echo ------------ Testing 'echo' [ON] --------------
6 echo 'singlequotedword'
7 echo "doublequotedword"
19 echo word@space@@space@
22 echo ------------ Testing 'echo' [OFF] --------------
24 echo 'singlequotedword'
25 echo "doublequotedword"
37 echo word@space@@space@
39 echo ------------ Testing redirection operators --------------
40 mkdir foobar & cd foobar
41 echo ...stdout redirection
52 echo ...stdout appending
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
85 echo bak ^&& echo baz 2> nul
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
105 echo ------------ Testing 'set' --------------
107 set FOOBAR 2> nul > nul
111 echo %FOOBAR%FOOBAR not defined
123 echo %FOOBAR%FOOBAR not defined
125 set FOOBA 2> nul > nul
135 echo %FOO%FOO not defined
140 echo set "FOO=bar" should not include the quotes in the variable value
145 echo ------------ Testing variable expansion --------------
147 echo ~dp0 should be directory containing batch file
163 echo %ERRORLEVEL%%ERRORLEVEL%
164 echo %ERRORLEVEL%ERRORLEVEL%
171 echo ------------ Testing variable delayed expansion --------------
172 rem NT4 doesn't support this
173 echo ...default mode (load-time expansion)
179 if %FOO% == bar (echo bar) else echo foo
185 if !FOO! == bar (echo bar) else echo foo
188 echo ...runtime (delayed) expansion mode
189 setlocal EnableDelayedExpansion
195 if %FOO% == bar (echo bar) else echo foo
201 if !FOO! == bar (echo bar) else echo foo
204 setlocal DisableDelayedExpansion
210 echo ...using /V cmd flag
211 echo @echo off> tmp.cmd
212 echo set FOO=foo>> tmp.cmd
213 echo echo %%FOO%%>> tmp.cmd
214 echo echo !FOO!>> tmp.cmd
215 echo set FOO=>> tmp.cmd
217 cmd /V:OfF /C tmp.cmd
220 echo ------------ Testing conditional execution --------------
221 echo ...unconditional ^&
222 call :setError 123 & echo foo1
223 echo bar2 & echo foo2
224 mkdir foobar & cd foobar
226 cd .. & rd /s/q foobar
228 echo foobar not deleted!
231 ) else echo foobar deleted
232 echo ...on success conditional ^&^&
233 call :setError 456 && echo foo3 > foo3
237 ) else echo foo3 not created
238 echo bar4 && echo foo4
239 echo ...on failure conditional ^|^|
240 call :setError 789 || echo foo5
241 echo foo6 || echo bar6 > bar6
247 echo ------------ Testing type ------------
257 echo ------------ Testing NUL ------------
258 md foobar & cd foobar
259 rem NUL file (non) creation + case insensitivity
260 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
269 rem NUL not special everywhere
272 if not exist foo (echo foo should have been created) else (
276 rem Empty file creation
288 echo ------------ Testing if/else --------------
289 echo if/else should work with blocks
291 echo if seems to work
293 echo if seems to be broken
296 echo else seems to be broken
298 echo else seems to work
301 echo if seems not to detect /c as parameter
303 echo parameter detection seems to be broken
305 echo Testing case sensitivity with and without /i option
306 if bar==BAR echo if does not default to case sensitivity
307 if not bar==BAR echo if seems to default to case sensitivity
308 if /i foo==FOO echo if /i seems to work
309 if /i not foo==FOO echo if /i seems to be broken
310 if /I foo==FOO echo if /I seems to work
311 if /I not foo==FOO echo if /I seems to be broken
313 echo -----------Testing for -----------
315 for %%i in (A B C) do echo %%i
316 for %%i in (A B C) do echo %%I
317 for %%i in (A B C) do echo %%j
318 for %%i in (A B C) do call :forTestFun1 %%i
319 for %%i in (1,4,1) do echo %%i
320 for %%i in (A, B,C) do echo %%i
321 for %%i in (X) do echo %%i
327 echo ...imbricated FORs
334 for %%i in (A B) do (
335 for %%j in (C D) do (
337 for %%i in (A B) do (
338 for %%j in (C D) do (
339 call :forTestFun2 %%i %%j ))
345 mkdir foobar & cd foobar
350 echo ...basic wildcards
351 for %%i in (ba*) do echo %%i
353 for /d %%i in (baz foo bar) do echo %%i
354 rem FIXME for /d incorrectly parses when wildcards are used
355 rem for /d %%i in (bazb*) do echo %%i
356 rem FIXME can't test wildcard expansion here since it's listed in directory
357 rem order, and not in alphabetic order.
358 rem Proper testing would need a currently missing "sort" program implementation.
359 rem for /d %%i in (ba*) do echo %%i>> tmp
362 rem for /d %%i in (?a*) do echo %%i>> tmp
365 rem for /d %%i in (*) do echo %%i>> tmp
371 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
372 for /L %%i in (1,2,0) do echo %%i
373 for /L %%i in (1,2,6) do echo %%i
374 for /l %%i in (1 ,2,6) do echo %%i
375 for /L %%i in (a,2,3) do echo %%i
376 for /L %%i in (1,2,-1) do echo %%i
377 for /L %%i in (-4,-1,-1) do echo %%i
378 for /L %%i in (1,-2,-2) do echo %%i
379 for /L %%i in (1,2,a) do echo %%i
380 echo ErrorLevel %ErrorLevel%
381 for /L %%i in (1,a,b) do echo %%i
382 echo ErrorLevel %ErrorLevel%
383 rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
384 rem for /L %%i in (a,2,b) do echo %%i
385 rem for /L %%i in (1,1,1) do echo %%i
386 rem for /L %%i in (1,-2,-1) do echo %%i
387 rem for /L %%i in (-1,-1,-1) do echo %%i
388 rem for /L %%i in (1,2, 3) do echo %%i
390 rem No output when using "set expr" syntax, unless in interactive mode
391 rem Need to use "set envvar=expr" to use in a batch script
392 echo ......individual operations
394 set /a var=1 +2 & echo %var%
395 set /a var=1 +-2 & echo %var%
396 set /a var=1 --2 & echo %var%
397 set /a var=2* 3 & echo %var%
398 set /a var=-2* -5 & echo %var%
399 set /a var=12/3 & echo %var%
400 set /a var=13/3 & echo %var%
401 set /a var=-13/3 & echo %var%
402 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
403 set /a var=5 %% 5 & echo %var%
404 set /a var=5 %% 3 & echo %var%
405 set /a var=5 %% -3 & echo %var%
406 set /a var=-5 %% -3 & echo %var%
407 set /a var=1 ^<^< 0 & echo %var%
408 set /a var=1 ^<^< 2 & echo %var%
409 set /a var=1 ^<^< -2 & echo %var%
410 set /a var=-1 ^<^< -2 & echo %var%
411 set /a var=-1 ^<^< 2 & echo %var%
412 set /a var=9 ^>^> 0 & echo %var%
413 set /a var=9 ^>^> 2 & echo %var%
414 set /a var=9 ^>^> -2 & echo %var%
415 set /a var=-9 ^>^> -2 & echo %var%
416 set /a var=-9 ^>^> 2 & echo %var%
417 set /a var=5 ^& 0 & echo %var%
418 set /a var=5 ^& 1 & echo %var%
419 set /a var=5 ^& 3 & echo %var%
420 set /a var=5 ^& 4 & echo %var%
421 set /a var=5 ^& 1 & echo %var%
422 set /a var=5 ^| 0 & echo %var%
423 set /a var=5 ^| 1 & echo %var%
424 set /a var=5 ^| 3 & echo %var%
425 set /a var=5 ^| 4 & echo %var%
426 set /a var=5 ^| 1 & echo %var%
427 set /a var=5 ^^ 0 & echo %var%
428 set /a var=5 ^^ 1 & echo %var%
429 set /a var=5 ^^ 3 & echo %var%
430 set /a var=5 ^^ 4 & echo %var%
431 set /a var=5 ^^ 1 & echo %var%
432 echo ......precedence and grouping
433 set /a var=4 + 2*3 & echo %var%
434 set /a var=(4+2)*3 & echo %var%
435 set /a var=4 * 3/5 & echo %var%
436 set /a var=(4 * 3)/5 & echo %var%
437 set /a var=4 * 5 %% 4 & echo %var%
438 set /a var=4 * (5 %% 4) & echo %var%
439 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
440 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
441 echo ......octal and hexadecimal
442 set /a var=0xf + 3 & echo %var%
443 set /a var=0xF + 3 & echo %var%
444 set /a var=015 + 2 & echo %var%
445 set /a var=3, 8+3,0 & echo %var%
447 set /a var=foo=3, foo+1 & echo %var%
448 if defined foo (echo %foo%) else (
451 set /a var=foo=3, foo+=1 & echo %var%
452 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
453 set /a var=foo*= foo & echo %var%
454 set /a var=whateverNonExistingVar & echo %var%
455 set /a var=whateverNonExistingVar + bar & echo %var%
456 set /a var=foo -= foo + 7 & echo %var%
457 set /a var=foo /= 3 + 2 & echo %var%
458 set /a var=foo=5, foo %%=2 & echo %var%
459 set /a var=foo ^<^<= 2 & echo %var%
460 set /a var=foo ^>^>= 2 & echo %var%
461 set /a var=foo ^&= 2 & echo %var%
462 set /a var=foo=5, foo ^|= 2 & echo %var%
463 set /a var=foo=5, foo ^^= 2 & echo %var%
464 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
469 echo -----------Testing del /a-----------
470 del /f/q *.test > nul
473 echo not-r > not-r.test
475 if not exist not-r.test echo not-r.test not found before delete, bad
477 if not exist not-r.test echo not-r.test not found after delete, good
479 if not exist r.test echo r.test not found before delete, bad
480 if exist r.test echo r.test found before delete, good
482 if not exist r.test echo r.test not found after delete, good
483 if exist r.test echo r.test found after delete, bad
485 echo ------------ Testing del /q --------------
490 rem If /q doesn't work, cmd will prompt and the test case should hang
492 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
493 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
497 echo ------------ Testing del /s --------------
501 echo there > file2.dat
503 echo bye > "file with spaces.dat"
505 del /s file1.dat > nul
506 del file2.dat /s > nul
507 del "file3.dat" /s > nul
508 del "file with spaces.dat" /s > nul
510 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
511 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
512 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
513 if exist "file with spaces.dat" del "file with spaces.dat"
517 echo ----------- Testing mkdir -----------
519 rem md and mkdir are synonymous
526 rem Creating an already existing directory/file must fail
535 rem Multi-level path creation
547 mkdir ..\..\..\foo\bar2
550 mkdir ..\..\..\foo\bar2
552 rmdir ..\..\..\foo\bar2
560 rem Trailing backslashes
563 if exist foo (rmdir foo & echo dir created
564 ) else ( echo dir not created )
568 echo mkdir ? gives errorlevel %ErrorLevel%
571 echo mkdir ?\foo gives errorlevel %ErrorLevel%
574 echo mkdir foo\? gives errorlevel %ErrorLevel%
575 if exist foo (rmdir foo & echo ok, foo created
576 ) else ( echo foo not created )
579 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
582 echo bad, foo not created
586 echo ok, foo\bar created
592 rem multiples directories at once
593 mkdir foobaz & cd foobaz
594 mkdir foo bar\baz foobar
595 if exist foo (echo foo created) else echo foo not created!
596 if exist bar (echo bar created) else echo bar not created!
597 if exist foobar (echo foobar created) else echo foobar not created!
598 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
603 echo mkdir foo\* errorlevel %ErrorLevel%
604 if exist foo (rmdir foo & echo ok, foo created
605 ) else ( echo bad, foo not created )
607 echo ----------- Testing rmdir -----------
609 rem rd and rmdir are synonymous
613 if not exist foobar echo dir removed
617 if not exist foobar echo dir removed
618 rem Removing nonexistent directory
621 rem Removing single-level directories
625 if exist foo echo file not removed
631 if exist foo echo non-empty dir not removed
636 if exist foo echo non-empty dir not removed
643 echo recursive rmdir succeeded
650 echo foo > foo\bar\brol
653 echo recursive rmdir succeeded
660 rem multiples directories at once
661 mkdir foobaz & cd foobaz
665 rd /s/q foo bar foobar
666 if not exist foo (echo foo removed) else echo foo not removed!
667 if not exist bar (echo bar removed) else echo bar not removed!
668 if not exist foobar (echo foobar removed) else echo foobar not removed!
669 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
673 echo ------------ Testing CALL --------------
674 mkdir foobar & cd foobar
676 echo echo foo %%1> foo.cmd
679 echo echo %%1 %%2 > foo.cmd
687 rem Internal routines
688 call :testRoutine :testRoutine
695 call :testRoutineArgs foo
696 call :testRoutineArgs foo bar
697 call :testRoutineArgs foo ""
698 call :testRoutineArgs "" bar
699 call :testRoutineArgs foo ''
700 call :testRoutineArgs '' bar
701 goto :endTestRoutineArgs
707 rem Should work for builtins...
710 if exist foo (echo foo created) else echo foo should exist!
712 set FOOBAZ_VAR=foobaz
713 call echo Should expand %FOOBAZ_VAR%
718 if 1==1 call del batfile
720 if exist batfile echo batfile shouldn't exist
721 rem ... but not for 'if' or 'for'
722 call if 1==1 echo bar 2> nul
725 call for %%i in (foo bar baz) do echo %%i 2> nul
727 rem First look for programs in the path before trying a builtin
728 echo echo non-builtin dir> dir.cmd
733 echo ------------ Testing setlocal/endlocal ------------
735 rem Note: setlocal EnableDelayedExtension already tested in the variable delayed expansion test section
736 mkdir foobar & cd foobar
737 echo ...enable/disable extensions
738 setlocal DisableEXTensions
739 echo ErrLev: %ErrorLevel%
741 echo ErrLev: %ErrorLevel%
742 echo @echo off> tmp.cmd
743 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
744 rem Enabled by default
746 cmd /E:OfF /C tmp.cmd
749 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
750 echo ...setlocal with corresponding endlocal
751 echo @echo off> test.cmd
752 echo echo %%VAR%%>> test.cmd
753 echo setlocal>> test.cmd
754 echo set VAR=localval>> test.cmd
755 echo echo %%VAR%%>> test.cmd
756 echo endlocal>> test.cmd
757 echo echo %%VAR%%>> test.cmd
762 echo ...setlocal with no corresponding endlocal
763 echo @echo off> test.cmd
764 echo echo %%VAR%%>> test.cmd
765 echo setlocal>> test.cmd
766 echo set VAR=localval>> test.cmd
767 echo echo %%VAR%%>> test.cmd
775 echo -----------Testing Errorlevel-----------
776 rem WARNING: Do *not* add tests using ErrorLevel after this section
777 should_not_exist 2> nul > nul
779 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
780 rem See http://www.robvanderwoude.com/exit.php
783 if errorlevel 2 echo errorlevel too high, bad
784 if errorlevel 1 echo errorlevel just right, good
786 echo abc%ErrorLevel%def
787 if errorlevel 1 echo errorlevel nonzero, bad
788 if not errorlevel 1 echo errorlevel zero, good
789 rem Now verify that setting a real variable hides its magic variable
791 echo %ErrorLevel% should be 7
792 if errorlevel 7 echo setting var worked too well, bad
794 echo %ErrorLevel% should still be 7
796 echo -----------Testing GOTO-----------
799 echo goto with no leading space worked
802 echo goto with a leading space worked
805 echo goto with a leading tab worked
808 echo goto with a following space worked
810 echo -----------Done, jumping to EOF-----------
812 rem Subroutine to set errorlevel and return
813 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
816 rem This line runs under cmd in windows NT 4, but not in more modern versions.