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
326 echo ...imbricated FORs
333 for %%i in (A B) do (
334 for %%j in (C D) do (
336 for %%i in (A B) do (
337 for %%j in (C D) do (
338 call :forTestFun2 %%i %%j ))
344 mkdir foobar & cd foobar
349 echo ...basic wildcards
350 for %%i in (ba*) do echo %%i
352 for /d %%i in (baz foo bar) do echo %%i
353 rem FIXME for /d incorrectly parses when wildcards are used
354 rem for /d %%i in (bazb*) do echo %%i
355 rem FIXME can't test wildcard expansion here since it's listed in directory
356 rem order, and not in alphabetic order.
357 rem Proper testing would need a currently missing "sort" program implementation.
358 rem for /d %%i in (ba*) do echo %%i>> tmp
361 rem for /d %%i in (?a*) do echo %%i>> tmp
364 rem for /d %%i in (*) do echo %%i>> tmp
370 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
371 for /L %%i in (1,2,0) do echo %%i
372 for /L %%i in (1,2,6) do echo %%i
373 for /l %%i in (1 ,2,6) do echo %%i
374 for /L %%i in (a,2,3) do echo %%i
375 for /L %%i in (1,2,-1) do echo %%i
376 for /L %%i in (-4,-1,-1) do echo %%i
377 for /L %%i in (1,-2,-2) do echo %%i
378 for /L %%i in (1,2,a) do echo %%i
379 echo ErrorLevel %ErrorLevel%
380 for /L %%i in (1,a,b) do echo %%i
381 echo ErrorLevel %ErrorLevel%
382 rem FIXME: following test cases cannot be currently tested due to an inconsistent/buggy 'for /L' parsing.
383 rem for /L %%i in (a,2,b) do echo %%i
384 rem for /L %%i in (1,1,1) do echo %%i
385 rem for /L %%i in (1,-2,-1) do echo %%i
386 rem for /L %%i in (-1,-1,-1) do echo %%i
387 rem for /L %%i in (1,2, 3) do echo %%i
389 rem No output when using "set expr" syntax, unless in interactive mode
390 rem Need to use "set envvar=expr" to use in a batch script
391 echo ......individual operations
393 set /a var=1 +2 & echo %var%
394 set /a var=1 +-2 & echo %var%
395 set /a var=1 --2 & echo %var%
396 set /a var=2* 3 & echo %var%
397 set /a var=-2* -5 & echo %var%
398 set /a var=12/3 & echo %var%
399 set /a var=13/3 & echo %var%
400 set /a var=-13/3 & echo %var%
401 rem FIXME Divide by zero should return an error, but error messages cannot be tested with current infrastructure
402 set /a var=5 %% 5 & echo %var%
403 set /a var=5 %% 3 & echo %var%
404 set /a var=5 %% -3 & echo %var%
405 set /a var=-5 %% -3 & echo %var%
406 set /a var=1 ^<^< 0 & echo %var%
407 set /a var=1 ^<^< 2 & 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=9 ^>^> 0 & echo %var%
412 set /a var=9 ^>^> 2 & 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=5 ^& 0 & echo %var%
417 set /a var=5 ^& 1 & echo %var%
418 set /a var=5 ^& 3 & echo %var%
419 set /a var=5 ^& 4 & echo %var%
420 set /a var=5 ^& 1 & echo %var%
421 set /a var=5 ^| 0 & echo %var%
422 set /a var=5 ^| 1 & echo %var%
423 set /a var=5 ^| 3 & echo %var%
424 set /a var=5 ^| 4 & echo %var%
425 set /a var=5 ^| 1 & echo %var%
426 set /a var=5 ^^ 0 & echo %var%
427 set /a var=5 ^^ 1 & echo %var%
428 set /a var=5 ^^ 3 & echo %var%
429 set /a var=5 ^^ 4 & echo %var%
430 set /a var=5 ^^ 1 & echo %var%
431 echo ......precedence and grouping
432 set /a var=4 + 2*3 & echo %var%
433 set /a var=(4+2)*3 & echo %var%
434 set /a var=4 * 3/5 & echo %var%
435 set /a var=(4 * 3)/5 & echo %var%
436 set /a var=4 * 5 %% 4 & echo %var%
437 set /a var=4 * (5 %% 4) & echo %var%
438 set /a var=3 %% (5 + 8 %% 3 ^^ 2) & echo %var%
439 set /a var=3 %% (5 + 8 %% 3 ^^ -2) & echo %var%
440 echo ......octal and hexadecimal
441 set /a var=0xf + 3 & echo %var%
442 set /a var=0xF + 3 & echo %var%
443 set /a var=015 + 2 & echo %var%
444 set /a var=3, 8+3,0 & echo %var%
446 set /a var=foo=3, foo+1 & echo %var%
447 if defined foo (echo %foo%) else (
450 set /a var=foo=3, foo+=1 & echo %var%
451 set /a var=foo=3, bar=1, bar+=foo, bar & echo %var%
452 set /a var=foo*= foo & echo %var%
453 set /a var=whateverNonExistingVar & echo %var%
454 set /a var=whateverNonExistingVar + bar & echo %var%
455 set /a var=foo -= foo + 7 & echo %var%
456 set /a var=foo /= 3 + 2 & echo %var%
457 set /a var=foo=5, foo %%=2 & echo %var%
458 set /a var=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=5, foo ^|= 2 & echo %var%
462 set /a var=foo=5, foo ^^= 2 & echo %var%
463 set /a var=foo=19, foo %%= 4 + (bar %%= 7) & echo.
468 echo -----------Testing del /a-----------
469 del /f/q *.test > nul
472 echo not-r > not-r.test
474 if not exist not-r.test echo not-r.test not found before delete, bad
476 if not exist not-r.test echo not-r.test not found after delete, good
478 if not exist r.test echo r.test not found before delete, bad
479 if exist r.test echo r.test found before delete, good
481 if not exist r.test echo r.test not found after delete, good
482 if exist r.test echo r.test found after delete, bad
484 echo ------------ Testing del /q --------------
489 rem If /q doesn't work, cmd will prompt and the test case should hang
491 for %%a in (1 2.dat) do if exist file%%a echo del /q * failed on file%%a
492 for %%a in (1 2.dat) do if not exist file%%a echo del /q * succeeded on file%%a
496 echo ------------ Testing del /s --------------
500 echo there > file2.dat
502 echo bye > "file with spaces.dat"
504 del /s file1.dat > nul
505 del file2.dat /s > nul
506 del "file3.dat" /s > nul
507 del "file with spaces.dat" /s > nul
509 for %%f in (1 2 3) do if exist file%%f.dat echo Del /s failed on file%%f
510 for %%f in (1 2 3) do if exist file%%f.dat del file%%f.dat
511 if exist "file with spaces.dat" echo Del /s failed on "file with spaces.dat"
512 if exist "file with spaces.dat" del "file with spaces.dat"
516 echo ----------- Testing mkdir -----------
518 rem md and mkdir are synonymous
525 rem Creating an already existing directory/file must fail
534 rem Multi-level path creation
546 mkdir ..\..\..\foo\bar2
549 mkdir ..\..\..\foo\bar2
551 rmdir ..\..\..\foo\bar2
559 rem Trailing backslashes
562 if exist foo (rmdir foo & echo dir created
563 ) else ( echo dir not created )
567 echo mkdir ? gives errorlevel %ErrorLevel%
570 echo mkdir ?\foo gives errorlevel %ErrorLevel%
573 echo mkdir foo\? gives errorlevel %ErrorLevel%
574 if exist foo (rmdir foo & echo ok, foo created
575 ) else ( echo foo not created )
578 echo mkdir foo\bar\? gives errorlevel %ErrorLevel%
581 echo bad, foo not created
585 echo ok, foo\bar created
591 rem multiples directories at once
592 mkdir foobaz & cd foobaz
593 mkdir foo bar\baz foobar
594 if exist foo (echo foo created) else echo foo not created!
595 if exist bar (echo bar created) else echo bar not created!
596 if exist foobar (echo foobar created) else echo foobar not created!
597 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
602 echo mkdir foo\* errorlevel %ErrorLevel%
603 if exist foo (rmdir foo & echo ok, foo created
604 ) else ( echo bad, foo not created )
606 echo ----------- Testing rmdir -----------
608 rem rd and rmdir are synonymous
612 if not exist foobar echo dir removed
616 if not exist foobar echo dir removed
617 rem Removing nonexistent directory
620 rem Removing single-level directories
624 if exist foo echo file not removed
630 if exist foo echo non-empty dir not removed
635 if exist foo echo non-empty dir not removed
642 echo recursive rmdir succeeded
649 echo foo > foo\bar\brol
652 echo recursive rmdir succeeded
659 rem multiples directories at once
660 mkdir foobaz & cd foobaz
664 rd /s/q foo bar foobar
665 if not exist foo (echo foo removed) else echo foo not removed!
666 if not exist bar (echo bar removed) else echo bar not removed!
667 if not exist foobar (echo foobar removed) else echo foobar not removed!
668 if not exist bar\baz (echo bar\baz removed) else echo bar\baz not removed!
672 echo ------------ Testing CALL --------------
673 mkdir foobar & cd foobar
675 echo echo foo %%1> foo.cmd
678 echo echo %%1 %%2 > foo.cmd
686 rem Internal routines
687 call :testRoutine :testRoutine
694 call :testRoutineArgs foo
695 call :testRoutineArgs foo bar
696 call :testRoutineArgs foo ""
697 call :testRoutineArgs "" bar
698 call :testRoutineArgs foo ''
699 call :testRoutineArgs '' bar
700 goto :endTestRoutineArgs
706 rem Should work for builtins...
709 if exist foo (echo foo created) else echo foo should exist!
711 set FOOBAZ_VAR=foobaz
712 call echo Should expand %FOOBAZ_VAR%
717 if 1==1 call del batfile
719 if exist batfile echo batfile shouldn't exist
720 rem ... but not for 'if' or 'for'
721 call if 1==1 echo bar 2> nul
724 call for %%i in (foo bar baz) do echo %%i 2> nul
726 rem First look for programs in the path before trying a builtin
727 echo echo non-builtin dir> dir.cmd
732 echo ------------ Testing setlocal/endlocal ------------
734 rem Note: setlocal EnableDelayedExtension already tested in the variable delayed expansion test section
735 mkdir foobar & cd foobar
736 echo ...enable/disable extensions
737 setlocal DisableEXTensions
738 echo ErrLev: %ErrorLevel%
740 echo ErrLev: %ErrorLevel%
741 echo @echo off> tmp.cmd
742 echo echo ErrLev: %%ErrorLevel%%>> tmp.cmd
743 rem Enabled by default
745 cmd /E:OfF /C tmp.cmd
748 rem FIXME: creating file before setting envvar value to prevent parsing-time evaluation (due to EnableDelayedExpansion not being implemented/available yet)
749 echo ...setlocal with corresponding endlocal
750 echo @echo off> test.cmd
751 echo echo %%VAR%%>> test.cmd
752 echo setlocal>> test.cmd
753 echo set VAR=localval>> test.cmd
754 echo echo %%VAR%%>> test.cmd
755 echo endlocal>> test.cmd
756 echo echo %%VAR%%>> test.cmd
761 echo ...setlocal with no corresponding endlocal
762 echo @echo off> test.cmd
763 echo echo %%VAR%%>> test.cmd
764 echo setlocal>> test.cmd
765 echo set VAR=localval>> test.cmd
766 echo echo %%VAR%%>> test.cmd
774 echo -----------Testing Errorlevel-----------
775 rem WARNING: Do *not* add tests using ErrorLevel after this section
776 should_not_exist 2> nul > nul
778 rem nt 4.0 doesn't really support a way of setting errorlevel, so this is weak
779 rem See http://www.robvanderwoude.com/exit.php
782 if errorlevel 2 echo errorlevel too high, bad
783 if errorlevel 1 echo errorlevel just right, good
785 echo abc%ErrorLevel%def
786 if errorlevel 1 echo errorlevel nonzero, bad
787 if not errorlevel 1 echo errorlevel zero, good
788 rem Now verify that setting a real variable hides its magic variable
790 echo %ErrorLevel% should be 7
791 if errorlevel 7 echo setting var worked too well, bad
793 echo %ErrorLevel% should still be 7
795 echo -----------Testing GOTO-----------
798 echo goto with no leading space worked
801 echo goto with a leading space worked
804 echo goto with a leading tab worked
807 echo goto with a following space worked
809 echo -----------Done, jumping to EOF-----------
811 rem Subroutine to set errorlevel and return
812 rem in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
815 rem This line runs under cmd in windows NT 4, but not in more modern versions.