https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7f8792e0056f6763cf2b3…
commit 7f8792e0056f6763cf2b3de0ca052a35f784fa8b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Jul 27 00:30:24 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Aug 19 20:35:58 2020 +0200
[CMD_ROSTEST] Add tests for batch execution flow with GOTO and CALL commands.
- Tests for GOTO across IF parenthesized block (parser test with line
continuation at closing parenthesis).
- Tests for showing how FOR-loops stop when a GOTO is encountered.
- Tests for EXIT command within IF block.
---
modules/rostests/win32/cmd/rsrc.rc | 6 +
modules/rostests/win32/cmd/test_goto_call.cmd | 239 ++++++++++++++++++++++
modules/rostests/win32/cmd/test_goto_call.cmd.exp | 214 +++++++++++++++++++
3 files changed, 459 insertions(+)
diff --git a/modules/rostests/win32/cmd/rsrc.rc b/modules/rostests/win32/cmd/rsrc.rc
index 7196b345f36..638cd3ae1a5 100644
--- a/modules/rostests/win32/cmd/rsrc.rc
+++ b/modules/rostests/win32/cmd/rsrc.rc
@@ -28,3 +28,9 @@ test_echoer_parser.cmd TESTCMD "test_echoer_parser.cmd"
/* @makedep: test_echoer_parser.cmd.exp */
test_echoer_parser.cmd.exp TESTOUT "test_echoer_parser.cmd.exp"
+
+/* @makedep: test_goto_call.cmd */
+test_goto_call.cmd TESTCMD "test_goto_call.cmd"
+
+/* @makedep: test_goto_call.cmd.exp */
+test_goto_call.cmd.exp TESTOUT "test_goto_call.cmd.exp"
diff --git a/modules/rostests/win32/cmd/test_goto_call.cmd
b/modules/rostests/win32/cmd/test_goto_call.cmd
new file mode 100644
index 00000000000..44add4cd9ec
--- /dev/null
+++ b/modules/rostests/win32/cmd/test_goto_call.cmd
@@ -0,0 +1,239 @@
+@echo off
+setlocal enableextensions
+setlocal enabledelayedexpansion
+
+
+::
+:: Tests for GOTO and CALL.
+::
+
+
+
+::
+:: Testing GOTO/CALL from and to within parenthesized blocks.
+::
+
+echo --------- Testing GOTO within block ---------
+(echo Block-test 1: Single-line& goto :block2 & echo Unexpected Block-test 1^^!)
+echo Unexpected echo 1^^!
+
+:block2
+(
+echo Block-test 2: Multi-line
+goto :block3
+echo Unexpected Block-test 2^^!
+)
+echo Unexpected echo 2-3^^!
+
+:test_call_block
+echo Test CALL in block OK from %0
+:: We exit this CALL invocation
+goto :EOF
+
+(
+:block3
+echo --------- Testing CALL within block ---------
+echo Block-test 3: CALL in block
+call :test_call_block
+echo CALL done
+)
+
+goto :block4
+echo Unexpected echo 4^^!
+(
+:block4
+echo Block-test 4 OK
+)
+
+
+::
+:: Testing GOTO/CALL from within FOR and IF.
+:: This is a situation similar to the parenthesized blocks.
+:: See bug-report CORE-13713
+::
+
+:: Testing CALL within FOR
+echo --------- Testing CALL within FOR ---------
+for /L %%A IN (0,1,3) DO (
+ set Number=%%A
+ if %%A==2 call :out_of_loop_1 %%A
+ if %%A==2 (echo %%A IS equal to 2) else (echo %%A IS NOT equal to 2)
+)
+goto :continue_2
+:out_of_loop_1
+echo Out of FOR 1 CALL from %0, number is %1
+:: We exit this CALL invocation
+goto :EOF
+:continue_2
+
+
+:: Testing GOTO within FOR
+echo --------- Testing GOTO within FOR ---------
+for /L %%A IN (0,1,3) DO (
+ set Number=%%A
+ if %%A==2 goto :out_of_loop_2
+ echo %%A IS NOT equal to 2
+)
+echo Unexpected FOR echo 2^^!
+:out_of_loop_2
+echo Out of FOR 2, number is %Number%
+
+
+
+::
+:: Show how each different FOR-loop stops when a GOTO is encountered.
+::
+echo --------- Testing FOR loop stopping with GOTO ---------
+
+:: FOR - Stops directly
+echo --- FOR
+@echo on
+for %%A in (1,2,3,4,5,6,7,8,9,10) do (
+ set Number=%%A
+ if %%A==5 goto :out_of_loop_2a
+)
+echo Unexpected FOR echo 2a^^!
+:out_of_loop_2a
+echo Out of FOR 2a, number is %Number%
+@echo off
+
+
+:: FOR /R - Stops directly
+echo --- FOR /R
+
+:: Use auxiliary directoreis to test for /R
+mkdir foobar && cd foobar
+mkdir foo1
+mkdir foo2
+mkdir bar1
+
+@echo on
+for /r %%A in (1,2,3,4,5,6,7,8,9,10) do (
+ set Number=%%~nA
+ if %%~nA==5 goto :out_of_loop_2b
+)
+echo Unexpected FOR echo 2b^^!
+:out_of_loop_2b
+echo Out of FOR 2b, number is %Number%
+@echo off
+
+:: Cleanup
+cd .. & rd /s/q foobar
+
+
+:: FOR /L - Does not stop directly. It continues looping until the end
+:: but does not execute its body code. This can cause problems e.g. for
+:: infinite loops "for /l %a in () do ( ... )" that are exited by EXIT /B,
+:: since the body code stops being executed, but the loop itself continues
+:: running forever.
+echo --- FOR /L
+@echo on
+for /l %%A in (1,1,10) do (
+ set Number=%%A
+ if %%A==5 goto :out_of_loop_2c
+)
+echo Unexpected FOR echo 2c^^!
+:out_of_loop_2c
+echo Out of FOR 2c, number is %Number%
+@echo off
+
+
+:: FOR /F - Stops directly.
+echo --- FOR /F
+@echo on
+for %%T in ( "1:2:3" "4:5:6:7" "8:9:10" ) do (
+ set "pc=%%~T"
+ for /f "delims=" %%A in (^"!pc::^=^
+% New line %
+!^") do (
+
+ set Number=%%A
+ if %%A==5 goto :out_of_loop_2d
+)
+)
+echo Unexpected FOR echo 2d^^!
+:out_of_loop_2d
+echo Out of FOR 2d, number is %Number%
+@echo off
+
+
+
+:: Testing CALL within IF
+echo --------- Testing CALL within IF ---------
+if 1==1 (
+ call :out_of_if_1 123
+ echo Success IF echo 1
+)
+goto :continue_3
+:out_of_if_1
+echo Out of IF CALL from %0, number is %1
+:: We exit this CALL invocation
+goto :EOF
+:continue_3
+
+
+:: Testing GOTO within IF
+echo --------- Testing GOTO within IF ---------
+if 1==1 (
+ goto :out_of_if_2
+ echo Unexpected IF echo 2a^^!
+)
+echo Unexpected IF echo 2b^^!
+:out_of_if_2
+echo Out of IF ok
+
+:: Same, but with line-continuation at the closing parenthesis of the IF block.
+if 1==1 (
+:labelA
+ echo A
+) ^
+else (
+:labelB
+ echo B
+ goto :continue
+)
+:: We are jumping inside the IF, whose block will be interpreted as
+:: separate commands; thus we will also run the :labelB block as well.
+goto :labelA
+
+
+::
+:: Next suite of tests.
+::
+:continue
+
+:: Testing EXIT within IF
+echo --------- Testing EXIT within IF ---------
+
+:: Use a CALL context, and we will only check EXIT /B.
+call :doExitIfTest 1
+call :doExitIfTest 2
+goto :finished
+
+:doExitIfTest
+if %1==1 (
+ echo First block
+ exit /b
+ echo Unexpected first block^^!
+) else (
+ echo Second block
+ exit /b
+ echo Unexpected second block^^!
+)
+echo You won't see this^^!
+exit /b
+
+
+
+::
+:: Finished!
+::
+:finished
+echo --------- Finished --------------
+goto :EOF
+
+:: Subroutine to set errorlevel and return
+:: in windows nt 4.0, this always sets errorlevel 1, since /b isn't supported
+:setError
+exit /B %1
+:: This line runs under cmd in windows NT 4, but not in more modern versions.
diff --git a/modules/rostests/win32/cmd/test_goto_call.cmd.exp
b/modules/rostests/win32/cmd/test_goto_call.cmd.exp
new file mode 100644
index 00000000000..802e6c5dca3
--- /dev/null
+++ b/modules/rostests/win32/cmd/test_goto_call.cmd.exp
@@ -0,0 +1,214 @@
+--------- Testing GOTO within block ---------
+Block-test 1: Single-line
+Block-test 2: Multi-line
+--------- Testing CALL within block ---------
+Block-test 3: CALL in block
+Test CALL in block OK from :test_call_block
+CALL done
+Block-test 4 OK
+--------- Testing CALL within FOR ---------
+0 IS NOT equal to 2
+1 IS NOT equal to 2
+Out of FOR 1 CALL from :out_of_loop_1, number is 2
+2 IS equal to 2
+3 IS NOT equal to 2
+--------- Testing GOTO within FOR ---------
+0 IS NOT equal to 2
+1 IS NOT equal to 2
+Out of FOR 2, number is 2
+--------- Testing FOR loop stopping with GOTO ---------
+--- FOR
+
+@pwd@>for %A in (1 2 3 4 5 6 7 8 9 10) do (
+set Number=%A@space@@space@
+ if %A == 5 goto :out_of_loop_2a@space@
+)@space@
+
+@pwd@>(
+set Number=1@space@@space@
+ if 1 == 5 goto :out_of_loop_2a@space@
+)@space@
+
+@pwd@>(
+set Number=2@space@@space@
+ if 2 == 5 goto :out_of_loop_2a@space@
+)@space@
+
+@pwd@>(
+set Number=3@space@@space@
+ if 3 == 5 goto :out_of_loop_2a@space@
+)@space@
+
+@pwd@>(
+set Number=4@space@@space@
+ if 4 == 5 goto :out_of_loop_2a@space@
+)@space@
+
+@pwd@>(
+set Number=5@space@@space@
+ if 5 == 5 goto :out_of_loop_2a@space@
+)@space@
+
+@pwd@>echo Out of FOR 2a, number is 5@space@
+Out of FOR 2a, number is 5
+--- FOR /R
+
+@pwd@\foobar>for /R %A in (1 2 3 4 5 6 7 8 9 10) do (
+set Number=%~nA@space@@space@
+ if %~nA == 5 goto :out_of_loop_2b@space@
+)@space@
+
+@pwd@\foobar>(
+set Number=1@space@@space@
+ if 1 == 5 goto :out_of_loop_2b@space@
+)@space@
+
+@pwd@\foobar>(
+set Number=2@space@@space@
+ if 2 == 5 goto :out_of_loop_2b@space@
+)@space@
+
+@pwd@\foobar>(
+set Number=3@space@@space@
+ if 3 == 5 goto :out_of_loop_2b@space@
+)@space@
+
+@pwd@\foobar>(
+set Number=4@space@@space@
+ if 4 == 5 goto :out_of_loop_2b@space@
+)@space@
+
+@pwd@\foobar>(
+set Number=5@space@@space@
+ if 5 == 5 goto :out_of_loop_2b@space@
+)@space@
+
+@pwd@\foobar>echo Out of FOR 2b, number is 5@space@
+Out of FOR 2b, number is 5
+--- FOR /L
+
+@pwd@>for /L %A in (1 1 10) do (
+set Number=%A@space@@space@
+ if %A == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=1@space@@space@
+ if 1 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=2@space@@space@
+ if 2 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=3@space@@space@
+ if 3 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=4@space@@space@
+ if 4 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=5@space@@space@
+ if 5 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=6@space@@space@
+ if 6 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=7@space@@space@
+ if 7 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=8@space@@space@
+ if 8 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=9@space@@space@
+ if 9 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>(
+set Number=10@space@@space@
+ if 10 == 5 goto :out_of_loop_2c@space@
+)@space@
+
+@pwd@>echo Out of FOR 2c, number is 5@space@
+Out of FOR 2c, number is 5
+--- FOR /F
+
+@pwd@>for %T in ("1:2:3" "4:5:6:7" "8:9:10") do (
+set "pc=%~T"@space@@space@
+ for /F "delims=" %A in ("!pc::=
+!") do (
+set Number=%A@space@@space@
+ if %A == 5 goto :out_of_loop_2d@space@
+)@space@
+)@space@
+
+@pwd@>(
+set "pc=1:2:3"@space@@space@
+ for /F "delims=" %A in ("!pc::=
+!") do (
+set Number=%A@space@@space@
+ if %A == 5 goto :out_of_loop_2d@space@
+)@space@
+)@space@
+
+@pwd@>(
+set Number=1@space@@space@
+ if 1 == 5 goto :out_of_loop_2d@space@
+)@space@
+
+@pwd@>(
+set Number=2@space@@space@
+ if 2 == 5 goto :out_of_loop_2d@space@
+)@space@
+
+@pwd@>(
+set Number=3@space@@space@
+ if 3 == 5 goto :out_of_loop_2d@space@
+)@space@
+
+@pwd@>(
+set "pc=4:5:6:7"@space@@space@
+ for /F "delims=" %A in ("!pc::=
+!") do (
+set Number=%A@space@@space@
+ if %A == 5 goto :out_of_loop_2d@space@
+)@space@
+)@space@
+
+@pwd@>(
+set Number=4@space@@space@
+ if 4 == 5 goto :out_of_loop_2d@space@
+)@space@
+
+@pwd@>(
+set Number=5@space@@space@
+ if 5 == 5 goto :out_of_loop_2d@space@
+)@space@
+
+@pwd@>echo Out of FOR 2d, number is 5@space@
+Out of FOR 2d, number is 5
+--------- Testing CALL within IF ---------
+Out of IF CALL from :out_of_if_1, number is 123
+Success IF echo 1
+--------- Testing GOTO within IF ---------
+Out of IF ok
+A
+A
+B
+--------- Testing EXIT within IF ---------
+First block
+Second block
+--------- Finished --------------