1 echo Tests for cmd's builtin commands
4 echo ------------ Testing 'echo' [ON] --------------
6 echo 'singlequotedword'
7 echo "doublequotedword"
19 echo word@space@@space@
23 echo@tab@word@tab@@space@
30 echo ------------ Testing 'echo' [OFF] --------------
32 echo 'singlequotedword'
33 echo "doublequotedword"
45 echo word@space@@space@
49 echo@tab@word@tab@@space@
55 echo ------------ Testing redirection operators --------------
56 mkdir foobar & cd foobar
57 echo ...stdout redirection
68 echo ...stdout appending
87 echo ------------ Testing ^^ escape character --------------
88 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
101 echo bak ^&& echo baz 2> nul
111 rem FIXME: echoing %FOO% gives an error (baz not recognized) but prematurely
112 rem exits the script on windows; redirecting stdout and/or stderr doesn't help
121 echo ------------ Testing 'set' --------------
123 set FOOBAR 2> nul > nul
127 echo %FOOBAR%FOOBAR not defined
139 echo %FOOBAR%FOOBAR not defined
141 set FOOBA 2> nul > nul
151 echo %FOO%FOO not defined
156 echo set "FOO=bar" should not include the quotes in the variable value
169 echo ------------ Testing variable expansion --------------
171 echo ~dp0 should be directory containing batch file
187 echo %ERRORLEVEL%%ERRORLEVEL%
188 echo %ERRORLEVEL%ERRORLEVEL%
195 echo ------------ Testing variable delayed expansion --------------
196 rem NT4 doesn't support this
197 echo ...default mode (load-time expansion)
203 if %FOO% == bar (echo bar) else echo foo
209 if !FOO! == bar (echo bar) else echo foo
212 echo ...runtime (delayed) expansion mode
213 setlocal EnableDelayedExpansion
219 if %FOO% == bar (echo bar) else echo foo
225 if !FOO! == bar (echo bar) else echo foo
228 setlocal DisableDelayedExpansion
234 echo ...using /V cmd flag
235 echo @echo off> tmp.cmd
236 echo set FOO=foo>> tmp.cmd
237 echo echo %%FOO%%>> tmp.cmd
238 echo echo !FOO!>> tmp.cmd
239 echo set FOO=>> tmp.cmd
241 cmd /V:OfF /C tmp.cmd
244 echo ------------ Testing conditional execution --------------
245 echo ...unconditional ^&
246 call :setError 123 & echo foo1
247 echo bar2 & echo foo2
248 mkdir foobar & cd foobar
250 cd .. & rd /s/q foobar
252 echo foobar not deleted!
255 ) else echo foobar deleted
256 echo ...on success conditional ^&^&
257 call :setError 456 && echo foo3 > foo3
261 ) else echo foo3 not created
262 echo bar4 && echo foo4
263 echo ...on failure conditional ^|^|
264 call :setError 789 || echo foo5
265 echo foo6 || echo bar6 > bar6
271 echo ------------ Testing cd ------------
274 echo blabla > singleFile
276 echo Current dir: %CD%
291 if not exist foobar (cd ..)
293 cd@tab@..@tab@@space@@tab@
295 if not exist foobar (cd ..)
303 cd "bar bak@space@"@tab@@space@
309 echo ------------ Testing type ------------
319 echo ------------ Testing NUL ------------
320 md foobar & cd foobar
321 rem NUL file (non) creation + case insensitivity
322 rem Note: "if exist" does not work with NUL, so to check for file existence we use a kludgy workaround
331 rem NUL not special everywhere
334 if not exist foo (echo foo should have been created) else (
338 rem Empty file creation
350 echo ------------ Testing if/else --------------
351 echo if/else should work with blocks
353 echo if seems to work
355 echo if seems to be broken
358 echo else seems to be broken
360 echo else seems to work
363 echo if seems not to detect /c as parameter
365 echo parameter detection seems to be broken
367 echo Testing case sensitivity with and without /i option
368 if bar==BAR echo if does not default to case sensitivity
369 if not bar==BAR echo if seems to default to case sensitivity
370 if /i foo==FOO echo if /i seems to work
371 if /i not foo==FOO echo if /i seems to be broken
372 if /I foo==FOO echo if /I seems to work
373 if /I not foo==FOO echo if /I seems to be broken
375 echo -----------Testing for -----------
377 for %%i in (A B C) do echo %%i
378 for %%i in (A B C) do echo %%I
379 for %%i in (A B C) do echo %%j
380 for %%i in (A B C) do call :forTestFun1 %%i
381 for %%i in (1,4,1) do echo %%i
382 for %%i in (A, B,C) do echo %%i
383 for %%i in (X) do echo %%i
384 for@tab@%%i in (X2) do echo %%i
385 for %%i in@tab@(X3) do echo %%i
386 for %%i in (@tab@ foo@tab@) do echo %%i
387 for@tab@ %%i in@tab@(@tab@M) do echo %%i
388 for %%i@tab@in (X)@tab@do@tab@echo %%i
389 for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
395 echo ...imbricated FORs
402 for %%i in (A B) do (
403 for %%j in (C D) do (
405 for %%i in (A B) do (
406 for %%j in (C D) do (
407 call :forTestFun2 %%i %%j ))
413 mkdir foobar & cd foobar
418 echo ...basic wildcards
419 for %%i in (ba*) do echo %%i
421 for /d %%i in (baz foo bar) do echo %%i
422 rem FIXME for /d incorrectly parses when wildcards are used
423 rem for /d %%i in (bazb*) do echo %%i
424 rem FIXME can't test wildcard expansion here since it's listed in directory
425 rem order, and not in alphabetic order.
426 rem Proper testing would need a currently missing "sort" program implementation.
427 rem for /d %%i in (ba*) do echo %%i>> tmp
430 rem for /d %%i in (?a*) do echo %%i>> tmp
433 rem for /d %%i in (*) do echo %%i>> tmp
439 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
440 for /L %%i in (1,2,0) do echo %%i
441 for /L %%i in (1,2,6) do echo %%i
442 for /l %%i in (1 ,2,6) do echo %%i
443 for /L %%i in (a,2,3) do echo %%i
444 for /L %%i in (1,2,-1) do echo %%i
445 for /L %%i in (-4,-1,-1) do echo %%i
446 for /L %%i in (1,-2,-2) do echo %%i
447 for /L %%i in (1,2,a) do echo %%i
448 echo ErrorLevel %ErrorLevel%
449 for /L %%i in (1,a,b) do echo %%i
450 echo ErrorLevel %ErrorLevel%
451 rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
452 rem for /L %%i in (a,2,b) do echo %%i
453 rem for /L %%i in (1,1,1) do echo %%i
454 rem for /L %%i in (1,-2,-1) do echo %%i
455 rem for /L %%i in (-1,-1,-1) do echo %%i
456 rem for /L %%i in (1,2, 3) do echo %%i
458 rem No output when using "set expr" syntax, unless in interactive mode
459 rem Need to use "set envvar=expr" to use in a batch script
460 echo ......individual operations
462 set /a var=1 +2 & echo %var%
463 set /a var=1 +-2 & echo %var%
464 set /a var=1 --2 & echo %var%
465 set /a var=2* 3 & echo %var%
466 set /a var=-2* -5 & echo %var%
467 set /a var=12/3 & echo %var%
468 set /a var=13/3 & echo %var%
469 set /a var=-13/3 & echo %var%
470 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
471 set /a var=5 %% 5 & echo %var%
472 set /a var=5 %% 3 & echo %var%
473 set /a var=5 %% -3 & echo %var%
474 set /a var=-5 %% -3 & echo %var%
475 set /a var=1 ^<^< 0 & echo %var%
476 set /a var=1 ^<^< 2 & echo %var%
477 set /a var=1 ^<^< -2 & echo %var%
478 set /a var=-1 ^<^< -2 & echo %var%
479 set /a var=-1 ^<^< 2 & echo %var%
480 set /a var=9 ^>^> 0 & echo %var%
481 set /a var=9 ^>^> 2 & echo %var%
482 set /a var=9 ^>^> -2 & echo %var%
483 set /a var=-9 ^>^> -2 & echo %var%
484 set /a var=-9 ^>^> 2 & echo %var%
485 set /a var=5 ^& 0 & echo %var%
486 set /a var=5 ^& 1 & echo %var%
487 set /a var=5 ^& 3 & echo %var%
488 set /a var=5 ^& 4 & echo %var%
489 set /a var=5 ^& 1 & echo %var%
490 set /a var=5 ^| 0 & echo %var%
491 set /a var=5 ^| 1 & echo %var%
492 set /a var=5 ^| 3 & echo %var%
493 set /a var=5 ^| 4 & echo %var%
494 set /a var=5 ^| 1 & echo %var%
495 set /a var=5 ^^ 0 & echo %var%
496 set /a var=5 ^^ 1 & echo %var%
497 set /a var=5 ^^ 3 & echo %var%
498 set /a var=5 ^^ 4 & echo %var%
499 set /a var=5 ^^ 1 & echo %var%
500 echo ......precedence and grouping
501 set /a var=4 + 2*3 & echo %var%
502 set /a var=(4+2)*3 & echo %var%
503 set /a var=4 * 3/5 & echo %var%
504 set /a var=(4 * 3)/5 & echo %var%
505 set /a var=4 * 5 %% 4 & echo %var%
506 set /a var=4 * (5 %% 4) & echo %var%
507 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
508 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
509 echo ......octal and hexadecimal
510 set /a var=0xf + 3 & echo %var%
511 set /a var=0xF + 3 & echo %var%
512 set /a var=015 + 2 & echo %var%
513 set /a var=3, 8+3,0 & echo %var%
515 set /a var=foo=3, foo+1 & echo %var%
516 if defined foo (echo %foo%) else (
519 set /a var=foo=3, foo+=1 & echo %var%
520 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
521 set /a var=foo*= foo & echo %var%
522 set /a var=whateverNonExistingVar & echo %var%
523 set /a var=whateverNonExistingVar + bar & echo %var%
524 set /a var=foo -= foo + 7 & echo %var%
525 set /a var=foo /= 3 + 2 & echo %var%
526 set /a var=foo=5, foo %%=2 & echo %var%
527 set /a var=foo ^<^<= 2 & echo %var%
528 set /a var=foo ^>^>= 2 & echo %var%
529 set /a var=foo ^&= 2 & echo %var%
530 set /a var=foo=5, foo ^|= 2 & echo %var%
531 set /a var=foo=5, foo ^^= 2 & echo %var%
532 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
537 echo -----------Testing del /a-----------
538 del /f/q *.test > nul
541 echo not-r > not-r.test
543 if not exist not-r.test echo not-r.test not found before delete, bad
545 if not exist not-r.test echo not-r.test not found after delete, good
547 if not exist r.test echo r.test not found before delete, bad
548 if exist r.test echo r.test found before delete, good
550 if not exist r.test echo r.test not found after delete, good
551 if exist r.test echo r.test found after delete, bad
553 echo ------------ Testing del /q --------------
558 rem If /q doesn't work, cmd will prompt and the test case should hang
560 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
561 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
565 echo ------------ Testing del /s --------------
569 echo there > file2.dat
571 echo bye > "file with spaces.dat"
573 del /s file1.dat > nul
574 del file2.dat /s > nul
575 del "file3.dat" /s > nul
576 del "file with spaces.dat" /s > nul
578 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
579 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
580 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
581 if exist "file with spaces.dat" del "file with spaces.dat"
585 echo ----------- Testing mkdir -----------
587 rem md and mkdir are synonymous
594 rem Creating an already existing directory/file must fail
603 rem Multi-level path creation
615 mkdir ..\..\..\foo\bar2
618 mkdir ..\..\..\foo\bar2
620 rmdir ..\..\..\foo\bar2
628 rem Trailing backslashes
631 if exist foo (rmdir foo & echo dir created
632 ) else ( echo dir not created )
636 echo mkdir ? gives errorlevel %ErrorLevel%
639 echo mkdir ?\foo gives errorlevel %ErrorLevel%
642 echo mkdir foo\? gives errorlevel %ErrorLevel%
643 if exist foo (rmdir foo & echo ok, foo created
644 ) else ( echo foo not created )
647 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
650 echo bad, foo not created
654 echo ok, foo\bar created
660 rem multiples directories at once
661 mkdir foobaz & cd foobaz
662 mkdir foo bar\baz foobar
663 if exist foo (echo foo created) else echo foo not created!
664 if exist bar (echo bar created) else echo bar not created!
665 if exist foobar (echo foobar created) else echo foobar not created!
666 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
671 echo mkdir foo\* errorlevel %ErrorLevel%
672 if exist foo (rmdir foo & echo ok, foo created
673 ) else ( echo bad, foo not created )
675 echo ----------- Testing rmdir -----------
677 rem rd and rmdir are synonymous
681 if not exist foobar echo dir removed
685 if not exist foobar echo dir removed
686 rem Removing nonexistent directory
689 rem Removing single-level directories
693 if exist foo echo file not removed
699 if exist foo echo non-empty dir not removed
704 if exist foo echo non-empty dir not removed
711 echo recursive rmdir succeeded
718 echo foo > foo\bar\brol
721 echo recursive rmdir succeeded
728 rem multiples directories at once
729 mkdir foobaz & cd foobaz
733 rd /s/q foo bar foobar
734 if not exist foo (echo foo removed) else echo foo not removed!
735 if not exist bar (echo bar removed) else echo bar not removed!
736 if not exist foobar (echo foobar removed) else echo foobar not removed!
737 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
741 echo ------------ Testing CALL --------------
742 mkdir foobar & cd foobar
744 echo echo foo %%1> foo.cmd
747 echo echo %%1 %%2 > foo.cmd
755 rem Internal routines
756 call :testRoutine :testRoutine
763 call :testRoutineArgs foo
764 call :testRoutineArgs foo bar
765 call :testRoutineArgs foo ""
766 call :testRoutineArgs "" bar
767 call :testRoutineArgs foo ''
768 call :testRoutineArgs '' bar
769 goto :endTestRoutineArgs
775 rem Should work for builtins...
778 if exist foo (echo foo created) else echo foo should exist!
780 set FOOBAZ_VAR=foobaz
781 call echo Should expand %FOOBAZ_VAR%
786 if 1==1 call del batfile
788 if exist batfile echo batfile shouldn't exist
789 rem ... but not for 'if' or 'for'
790 call if 1==1 echo bar 2> nul
793 call for %%i in (foo bar baz) do echo %%i 2> nul
795 rem First look for programs in the path before trying a builtin
796 echo echo non-builtin dir> dir.cmd
801 echo ------------ Testing setlocal/endlocal ------------
803 rem Note: setlocal EnableDelayedExtension already tested in the variable delayed expansion test section
804 mkdir foobar & cd foobar
805 echo ...enable/disable extensions
806 setlocal DisableEXTensions
807 echo ErrLev: %ErrorLevel%
809 echo ErrLev: %ErrorLevel%
810 echo @echo off> tmp.cmd
811 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
812 rem Enabled by default
814 cmd /E:OfF /C tmp.cmd
817 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
818 echo ...setlocal with corresponding endlocal
819 echo @echo off> test.cmd
820 echo echo %%VAR%%>> test.cmd
821 echo setlocal>> test.cmd
822 echo set VAR=localval>> test.cmd
823 echo echo %%VAR%%>> test.cmd
824 echo endlocal>> test.cmd
825 echo echo %%VAR%%>> test.cmd
830 echo ...setlocal with no corresponding endlocal
831 echo @echo off> test.cmd
832 echo echo %%VAR%%>> test.cmd
833 echo setlocal>> test.cmd
834 echo set VAR=localval>> test.cmd
835 echo echo %%VAR%%>> test.cmd
843 echo -----------Testing Errorlevel-----------
844 rem WARNING: Do *not* add tests using ErrorLevel after this section
845 should_not_exist 2> nul > nul
847 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
848 rem See http://www.robvanderwoude.com/exit.php
851 if errorlevel 2 echo errorlevel too high, bad
852 if errorlevel 1 echo errorlevel just right, good
854 echo abc%ErrorLevel%def
855 if errorlevel 1 echo errorlevel nonzero, bad
856 if not errorlevel 1 echo errorlevel zero, good
857 rem Now verify that setting a real variable hides its magic variable
859 echo %ErrorLevel% should be 7
860 if errorlevel 7 echo setting var worked too well, bad
862 echo %ErrorLevel% should still be 7
864 echo -----------Testing GOTO-----------
867 echo goto with no leading space worked
870 echo goto with a leading space worked
873 echo goto with a leading tab worked
876 echo goto with a following space worked
878 echo -----------Done, jumping to EOF-----------
880 rem Subroutine to set errorlevel and return
881 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
884 rem This line runs under cmd in windows NT 4, but not in more modern versions.