diff --git a/IDE test results.html b/IDE test results.html new file mode 100644 index 0000000..d24f494 --- /dev/null +++ b/IDE test results.html @@ -0,0 +1,6715 @@ + + + + + + +
+| Test Suite: _SelBlocks-TestSuite.html |
| Test cases: 58 total / 57 passed / 1 failed |
| Commands: 989 total / 904 passed / 1 failed / 84 skipped |
| Test case: README | |||
| -- SelBench is required for this testsuite | +|||
| open | +http://htmlpreview.github.io/?https://github.com/refactoror/SelBlocks/blob/master/sel-blocksTests/_SelBlocks-testpage.html | ++ | + |
| Test case: eval | |||
| resetEmitted | ++ | + | + |
| --- isOneOf() | +|||
| emit | +"dilbert".isOneOf("dilbert","dogbert","mordac") | ++ | + |
| emit | +"bob".isOneOf("dilbert","dogbert","mordac") | ++ | + |
| --- mapTo() | +|||
| emit | +"red".mapTo("primary", ["red","green","blue"]) | ++ | + |
| emit | +"orange".mapTo("primary", ["red","green","blue"]) | ++ | + |
| --- translate() | +|||
| emit | +"red".translate("e", "E") | ++ | + |
| emit | +"red".translate(["red", "green", "blue"], ["blue", "red", "green"]) | ++ | + |
| --- check results | +|||
| assertEmitted | +"true~false~primary~orange~rEd~blue" | ++ | + |
| Test case: branching | |||
| resetEmitted | ++ | + | + |
| emit | +"BEFORE" | ++ | + |
| goto | +HERE | ++ | + |
| emit | +"A" | ++ | + |
| label | +HERE | ++ | + |
| gotoIf | +true | +THERE | ++ |
| emit | +"B" | ++ | + |
| label | +THERE | ++ | + |
| skipNext | ++ | + | + |
| emit | +"C" | ++ | + |
| emit | +"AFTER" | ++ | + |
| assertEmitted | +"BEFORE~AFTER" | ++ | + |
| === Error validations | +|||
| -!- | +|||
| expectError | +"Target label 'NOWHERE' is not found" | ++ | + |
| goto | +NOWHERE | ++ | + |
| -!- | +|||
| expectError | +"Target label 'NOWHERE' is not found" | ++ | + |
| gotoIf | +true | +NOWHERE | ++ |
| -!- | +|||
| expectError | +"Requires a number > 1" | ++ | + |
| skipNext | +-1 | ++ | + |
| -!- | +|||
| expectError | +/.*random.* (is not |is un)defined/ | ++ | + |
| skipNext | +random | ++ | + |
| Test case: if-1 | |||
| resetEmitted | ++ | + | + |
| emit | +"BEFORE" | ++ | + |
| -- | +|||
| if | +true | ++ | + |
| emit | +"truthy" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"falsey" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +true | ++ | + |
| emit | +"A" | ++ | + |
| else | ++ | + | + |
| emit | +"B" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"X" | ++ | + |
| else | ++ | + | + |
| emit | +"Y" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"false teeth" | ++ | + |
| else | ++ | + | + |
| if | +true | ++ | + |
| emit | +"truthF" | ++ | + |
| else | ++ | + | + |
| emit | +"false false" | ++ | + |
| endIf | ++ | + | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +"dilbert".isOneOf("dogbert","dilbert","wally") | ++ | + |
| emit | +"office mate" | ++ | + |
| endIf | ++ | + | + |
| if | +"dilbert".isOneOf("ratbert","alice","asok") | ++ | + |
| emit | +"mate" | ++ | + |
| else | ++ | + | + |
| emit | +"coffee mate" | ++ | + |
| endIf | ++ | + | + |
| if | +"mordac".isOneOf("bob the dinosaur","garbage man","mordac") | ++ | + |
| emit | +"cell mate" | ++ | + |
| else | ++ | + | + |
| emit | +"don't wait" | ++ | + |
| endIf | ++ | + | + |
| emit | +"AFTER" | ++ | + |
| --- check results | +|||
| assertEmitted | +"BEFORE~truthy~A~Y~truthF~office mate~coffee mate~cell mate~AFTER" | ++ | + |
| Test case: if-2 | |||
| resetEmitted | ++ | + | + |
| == | +|||
| if | +true | ++ | + |
| emit | +"if-y" | ++ | + |
| elseIf | +true | ++ | + |
| emit | +"elseIf-y" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"if-y" | ++ | + |
| elseIf | +true | ++ | + |
| emit | +"elseIf-y" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"if-y" | ++ | + |
| elseIf | +true | ++ | + |
| emit | +"elseIf-a1y" | ++ | + |
| elseIf | +true | ++ | + |
| emit | +"else-a2y" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"if-y" | ++ | + |
| elseIf | +false | ++ | + |
| emit | +"elseIf-b1y" | ++ | + |
| elseIf | +true | ++ | + |
| emit | +"elseIf-b2y" | ++ | + |
| endIf | ++ | + | + |
| -- | +|||
| if | +false | ++ | + |
| emit | +"if-y" | ++ | + |
| elseIf | +false | ++ | + |
| emit | +"elseIf-y" | ++ | + |
| else | ++ | + | + |
| emit | +"else-y" | ++ | + |
| endIf | ++ | + | + |
| assertEmitted | +"if-y~elseIf-y~elseIf-a1y~elseIf-b2y~else-y" | ++ | + |
| Test case: if-3 | |||
| resetEmitted | ++ | + | + |
| -- | +|||
| foreach | +i | +2, 0, 1, 4, 3, 5 | ++ |
| if | +i == 0 | ++ | + |
| emit | +"if-${i}" | ++ | + |
| elseIf | +i == 1 | ++ | + |
| emit | +"elseIf-${i}" | ++ | + |
| elseIf | +i == 2 | ++ | + |
| emit | +"elseIf-${i}" | ++ | + |
| elseIf | +i == 3 | ++ | + |
| emit | +"elseIf-${i}" | ++ | + |
| else | ++ | + | + |
| emit | +"else-${i}" | ++ | + |
| endIf | ++ | + | + |
| endForeach | ++ | + | + |
| assertEmitted | +"elseIf-2~if-0~elseIf-1~else-4~elseIf-3~else-5" | ++ | + |
| Test case: try - noop | |||
| log | +"-- no-op try --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +t-noop | ++ | + |
| emit | +"trying" | ++ | + |
| endTry | +t-noop | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~/])" | ++ | + |
| Test case: try - finally with no error | |||
| log | +"-- try/finally, w/no error --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +t-fin | ++ | + |
| emit | +"trying" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~finally~/])" | ++ | + |
| Test case: try - catch but no error | |||
| log | +"-- try/catch, but no error --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +tc0 | ++ | + |
| emit | +"trying" | ++ | + |
| catch | ++ | + | + |
| assertEval | +"should NEVER enter this catch block due to no error" | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~/])" | ++ | + |
| Test case: try - catch specific error | |||
| log | +"-- catch specific error --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +tc1 | ++ | + |
| throw | +"blamo catch ALL" | ++ | + |
| assertEval | +"this command should not be reached, due to thrown" | ++ | + |
| catch | ++ | + | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~caught 'blamo catch ALL'~/])" | ++ | + |
| Test case: try - catch specific error then finally | |||
| log | +"-- catch specific error, then finally --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +t-spec-outer | ++ | + |
| emit | +"trying outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"([/" | ++ | + |
| v v v | +|||
| try | +t-spec-inner | ++ | + |
| emit | +"trying inner" | ++ | + |
| throw | +"blamo inner" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| catch | +/blamo inner/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +t-spec-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| endTry | +t-spec-outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying outer~([/~trying inner~caught 'blamo inner'~finally~/])~/])" | ++ | + |
| Test case: try - catch throw finally throw | |||
| log | +"-- catch/throw, finally/throw --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +tcf-trap | ++ | + |
| v v v | +|||
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| try | +tcf | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"throwing A" | ++ | + |
| throw | +"blamoA" | ++ | + |
| assertEval | +"this command should not be reached, due to thrown" | ++ | + |
| catch | +/blamoA/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| emit | +"throwing B" | ++ | + |
| throw | +"blamoB" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| emit | +"throwing C" | ++ | + |
| throw | +"blamoC" | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| catch | ++ | + | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~throwing A~caught 'blamoA'~throwing B~finally~throwing C~caught 'blamoC'~/])" | ++ | + |
| Test case: try - bubble up to catch ALL | |||
| log | +"-- bubble up to catch ALL --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +t-all-outer | ++ | + |
| emit | +"trying-outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +t-all-inner | ++ | + |
| emit | +"trying" | ++ | + |
| throw | +"blamo try-catch-finally" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| catch | +/will NOT catch it/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| endTry | +t-all-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| catch | ++ | + | + |
| emit | +"caught-outer '" + _error.message + "'" | ++ | + |
| endTry | +t-all-outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying-outer~trying~caught-outer 'blamo try-catch-finally'~/])" | ++ | + |
| Test case: try - bubble up to catch ALL via finally | |||
| log | +"-- bubble up to catch ALL via finally --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +t-allfin-outer | ++ | + |
| emit | +"trying-outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +t-allfin-inner | ++ | + |
| emit | +"trying" | ++ | + |
| throw | +"blamo try-catch-finally" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| catch | +/will NOT catch it/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +t-allfin-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| catch | ++ | + | + |
| emit | +"caught-outer '" + _error.message + "'" | ++ | + |
| endTry | +t-allfin-outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying-outer~trying~finally~caught-outer 'blamo try-catch-finally'~/])" | ++ | + |
| Test case: try - bubble up out of noop try to catch specific error | |||
| log | +"-- bubble out of no-op try to catch specific error --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +noop-outer | ++ | + |
| emit | +"trying outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +op-inner | ++ | + |
| emit | +"trying inner" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +1 | ++ |
| emit | +"throwing inner" | ++ | + |
| throw | +"blamo" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| endTry | +op-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| catch | +/blamo/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +noop-outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying outer~trying inner~throwing inner~caught 'blamo'~finally~/])" | ++ | + |
| Test case: try - bubble up to catch specific error | |||
| log | +"-- bubble up to catch specific error --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +bub-spec-outer | ++ | + |
| emit | +"trying outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +bub-spec-inner | ++ | + |
| emit | +"trying inner" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +1 | ++ |
| emit | +"throwing inner" | ++ | + |
| throw | +"blamo" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +bub-spec-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| catch | +/blamo/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| endTry | +bub-spec-outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying outer~trying inner~throwing inner~finally~caught 'blamo'~/])" | ++ | + |
| Test case: try - bubble up to catch specific error via finally | |||
| log | +"-- bubble up to catch specific error via finally --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +bub-spec-outer | ++ | + |
| emit | +"trying outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +bub-spec-inner | ++ | + |
| emit | +"trying inner" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +1 | ++ |
| emit | +"throwing inner" | ++ | + |
| throw | +"blamo" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +bub-spec-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| catch | +/blamo/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +bub-spec-outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying outer~trying inner~throwing inner~finally~caught 'blamo'~finally~/])" | ++ | + |
| Test case: try - throw catch rethrow | |||
| log | +"-- throw, catch, rethrow --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +outer | ++ | + |
| emit | +"trying outer" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +inner | ++ | + |
| emit | +"trying inner" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +1 | ++ |
| emit | +"throwing blamo1" | ++ | + |
| throw | +"blamo1" | ++ | + |
| assertEval | +"this command should not be reached, due to throw" | ++ | + |
| catch | +/blamo1/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| emit | +"throwing blamo2" | ++ | + |
| throw | +"blamo2" | ++ | + |
| endTry | +inner | ++ | + |
| ^ ^ ^ ^ | +|||
| catch | +/blamo2/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| endTry | +outer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying outer~trying inner~throwing blamo1~caught 'blamo1'~throwing blamo2~caught 'blamo2'~/])" | ++ | + |
| Test case: try - bubble out of nested function calls | |||
| log | +"-- bubble out of nested function calls --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +bub-invoke | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"calling" | ++ | + |
| call | +subBub | +n = 0 | ++ |
| assertEval | +"this command should not be reached, due error thrown in function" | ++ | + |
| catch | +/blamo/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| finally | ++ | + | + |
| emit | +"finally" | ++ | + |
| endTry | +bub-invoke | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| ^ ^ ^ ^ | +|||
| function | +subBub | +n | ++ |
| v v v | +|||
| try | +tcf-inner | ++ | + |
| emit | +"${n}) trying-inner" | ++ | + |
| if | +n < 2 | ++ | + |
| emit | +"${n}) calling" | ++ | + |
| call | +subBub | +n = n+1 | ++ |
| else | ++ | + | + |
| emit | +"${n}) throwing" | ++ | + |
| throw | +"blamo" | ++ | + |
| endIf | ++ | + | + |
| finally | ++ | + | + |
| emit | +"${n}) finally" | ++ | + |
| endTry | +tcf-inner | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| endFunction | ++ | + | + |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~calling~0) trying-inner~0) calling~1) trying-inner~1) calling~2) trying-inner~2) throwing~2) finally~1) finally~0) finally~caught 'blamo'~finally~/])" | ++ | + |
| Test case: try - command bubbling break with finally | |||
| log | +"-- command bubbling, break w/finally --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| emit | +"while'g" | ++ | + |
| for | +w=3; w > 0; w-- | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +breaker | ++ | + |
| emit | +"${w}) trying" | ++ | + |
| if | +w==2 | ++ | + |
| emit | +"${w}) BREAK" | ++ | + |
| break | ++ | + | + |
| endIf | ++ | + | + |
| finally | ++ | + | + |
| emit | +"${w}) finallying" | ++ | + |
| endTry | +breaker | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"${w}) iterating" | ++ | + |
| endFor | ++ | + | + |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~while'g~3) trying~3) finallying~3) iterating~2) trying~2) BREAK~2) finallying~/])" | ++ | + |
| Test case: try - command bubbling intra try break | |||
| log | +"-- command bubbling, intra-try break --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +breaker | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"while'g" | ++ | + |
| for | +w=3; w > 0; w-- | ++ | + |
| if | +w==2 | ++ | + |
| emit | +"${w}) BREAK" | ++ | + |
| break | ++ | + | + |
| endIf | ++ | + | + |
| emit | +"${w}) iterating" | ++ | + |
| endFor | ++ | + | + |
| finally | ++ | + | + |
| emit | +"finallying" | ++ | + |
| endTry | +breaker | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~while'g~3) iterating~2) BREAK~finallying~/])" | ++ | + |
| Test case: try - command bubbling continue with finally | |||
| log | +"-- command bubbling, continue w/finally --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| emit | +"while'g" | ++ | + |
| for | +w=3; w > 0; w-- | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +continuer | ++ | + |
| emit | +"${w}) trying" | ++ | + |
| if | +w==2 | ++ | + |
| emit | +"${w}) CONTINUE" | ++ | + |
| continue | ++ | + | + |
| endIf | ++ | + | + |
| finally | ++ | + | + |
| emit | +"${w}) finallying" | ++ | + |
| endTry | +continuer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"${w}) iterating" | ++ | + |
| endFor | ++ | + | + |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~while'g~3) trying~3) finallying~3) iterating~2) trying~2) CONTINUE~2) finallying~1) trying~1) finallying~1) iterating~/])" | ++ | + |
| Test case: try - command bubbling intra try continue | |||
| log | +"-- command bubbling, intra-try continue --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +continuer | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"while'g" | ++ | + |
| for | +w=3; w > 0; w-- | ++ | + |
| if | +w==2 | ++ | + |
| emit | +"${w}) CONTINUE" | ++ | + |
| continue | ++ | + | + |
| endIf | ++ | + | + |
| emit | +"${w}) iterating" | ++ | + |
| endFor | ++ | + | + |
| finally | ++ | + | + |
| emit | +"finallying" | ++ | + |
| endTry | +continuer | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~trying~while'g~3) iterating~2) CONTINUE~1) iterating~finallying~/])" | ++ | + |
| Test case: try - command bubbling error replaced by return | |||
| log | +"-- command bubbling, error replaced by return --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| emit | +"calling" | ++ | + |
| call | +cmdBubA | ++ | + |
| emit | +"returned ${_result}" | ++ | + |
| function | +cmdBubA | ++ | + |
| emit | +"in cmdBubA" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +cmdBub-tcf | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"returning (1)" | ++ | + |
| return | +1 | ++ | + |
| finally | ++ | + | + |
| emit | +"finallying" | ++ | + |
| emit | +"returning (2)" | ++ | + |
| return | +2 | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +"this command should not be reached, due to return/return above" | ++ | + |
| endFunction | ++ | + | + |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~calling~in cmdBubA~trying~returning (1)~finallying~returning (2)~returned 2~/])" | ++ | + |
| Test case: try - command bubbling error replaced by return 2 | |||
| log | +"-- command bubbling, error replaced by return --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| emit | +"calling" | ++ | + |
| call | +cmdBubB | ++ | + |
| emit | +"returned ${_result}" | ++ | + |
| function | +cmdBubB | ++ | + |
| emit | +"in cmdBubB" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +cmdBub-tcf | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"throwing" | ++ | + |
| throw | +"short-lived error" | ++ | + |
| finally | ++ | + | + |
| emit | +"finallying" | ++ | + |
| emit | +"returning (2)" | ++ | + |
| return | +2 | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| assertEval | +"this command should not be reached, due to throw/return above" | ++ | + |
| endFunction | ++ | + | + |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~calling~in cmdBubB~trying~throwing~finallying~returning (2)~returned 2~/])" | ++ | + |
| Test case: try - command bubbling return replaced by error | |||
| log | +"-- command bubbling, return replaced by error --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| emit | +"calling" | ++ | + |
| call | +cmdBubC | ++ | + |
| emit | +"returned ${_result}" | ++ | + |
| function | +cmdBubC | ++ | + |
| emit | +"in cmdBubC" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +cmdBub-tcf-guardrail | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| v v v | +|||
| try | +cmdBub-tcf | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"returning (1)" | ++ | + |
| return | +1 | ++ | + |
| finally | ++ | + | + |
| emit | +"finallying" | ++ | + |
| emit | +"throwing" | ++ | + |
| throw | +"this-error-replaces-return-1" | ++ | + |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| catch | +/this-error-replaces-return-1/ | ++ | + |
| emit | +"caught '" + _error.message + "'" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +0 | ++ |
| endTry | ++ | + | + |
| ^ ^ ^ ^ | +|||
| endFunction | ++ | + | + |
| emit | +"/])" | ++ | + |
| assertEmitted | +"([/~calling~in cmdBubC~trying~returning (1)~finallying~throwing~caught 'this-error-replaces-return-1'~returned ${_result}~/])" | ++ | + |
| Test case: try - exitTest with finally processing | |||
| log | +"-- exitTest w/finally processing --" | ++ | + |
| resetEmitted | ++ | + | + |
| emit | +"([/" | ++ | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +abort | ++ | + |
| emit | +"trying" | ++ | + |
| emit | +"exitTest ..." | ++ | + |
| exitTest | ++ | + | + |
| finally | ++ | + | + |
| emit | +"finallying" | ++ | + |
| assertEmitted | +"([/~trying~exitTest ...~finallying" | ++ | + |
| resetEmitted | ++ | + | + |
| endTry | +abort | ++ | + |
| ^ ^ ^ ^ | +|||
| assertEval | +"this command should not be reached, due to exitTest above" | ++ | + |
| Test case: try - try without matching catch | |||
| log | +"-- try without matching catch --" | ++ | + |
| resetEmitted | ++ | + | + |
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| v v v | +|||
| try | +miss | ++ | + |
| assertEval | +true | +true | ++ |
| throw | +"blamo will NOT be caught at all" | ++ | + |
| assertEval | +"this command should not be reached" | ++ | + |
| catch | +/will NOT catch it/ | ++ | + |
| log | +"caught miss '" + _error.message + "'" | ++ | + |
| finally | ++ | + | + |
| log | +"finally" | ++ | + |
| endTry | +miss | ++ | Command execution failure. Please search the user group at https://groups.google.com/forum/#!forum/selenium-users for error details from the log window. The error message is: blamo will NOT be caught at all | +
| ^ ^ ^ ^ | +|||
| assertEval | +selblocks.tcf.nestingLevel | +-1 | ++ |
| emit | +"trying" | ++ | + |
| Test case: while | |||
| resetEmitted | ++ | + | + |
| deleteVars | +w | ++ | + |
| store | +3 | +w | ++ |
| emit | +"START: ${w}" | ++ | + |
| --- no iterations | +|||
| while | +w == 42 | ++ | + |
| emit | +"SHOULD NEVER HAPPEN" | ++ | + |
| endWhile | ++ | + | + |
| --- several iterations | +|||
| while | +w > 0 | ++ | + |
| emit | +"iter=${w}" | ++ | + |
| storeEval | +${w}-1 | +w | ++ |
| endWhile | ++ | + | + |
| emit | +"END: ${w}" | ++ | + |
| --- check results | +|||
| assertEmitted | +"START: 3~iter=3~iter=2~iter=1~END: 3" | ++ | + |
| Test case: for | |||
| resetEmitted | ++ | + | + |
| deleteVars | +f | ++ | + |
| emit | +"START ${f}" | ++ | + |
| for | +s=0,f=3; f <= 5; f++ | ++ | + |
| emit | +"iter=${f}.${s}" | ++ | + |
| endFor | ++ | + | + |
| emit | +"END ${f}" | ++ | + |
| --- check results | +|||
| assertEmitted | +"START ${commands}quot; + "{f}~iter=3.0~iter=4.0~iter=5.0~END ${commands}quot; + "{f}" | ++ | + |
| Test case: foreach | |||
| resetEmitted | ++ | + | + |
| deleteVars | +_i, fe | ++ | + |
| emit | +"START ${_i}-${fe}" | ++ | + |
| foreach | +fe | +"dilbert", "dogbert", "wally" | ++ |
| emit | +"${_i}) ${fe}" | ++ | + |
| endForeach | ++ | + | + |
| emit | +"END ${_i}-${fe}" | ++ | + |
| --- check results | +|||
| assertEmitted | +"START ${commands}quot; + "{_i}-${commands}quot; + "{fe}~0) dilbert~1) dogbert~2) wally~END ${commands}quot; + "{_i}-${commands}quot; + "{fe}" | ++ | + |
| Test case: foreach-xpath | |||
| resetEmitted | ++ | + | + |
| echo | +$x("//input") | ++ | + |
| echo | +$X("//input") | ++ | + |
| echo | +begin | ++ | + |
| emit | +"START ${_i}) ${link}" | ++ | + |
| foreach | +link | +$X("//input") | ++ |
| emit | +"${_i}) ${link}" | ++ | + |
| echo | +${link} | ++ | + |
| endForeach | ++ | + | + |
| emit | +"END ${_i}) ${link}" | ++ | + |
| assertEmitted | +"START ${" + "_i}) ${" + "link}~0) [object HTMLInputElement]~1) [object HTMLInputElement]~2) [object HTMLInputElement]~END ${" + "_i}) ${" + "link}" | ++ | + |
| Test case: forjson | |||
| if | +globalContext.onServer === true | ++ | + |
| store | +../data/forjson.json | +forJsonFileName | ++ |
| else | ++ | + | + |
| store | +data/forjson.json | +forJsonFileName | ++ |
| endIf | ++ | + | + |
| resetEmitted | ++ | + | + |
| deleteVars | +jname | ++ | + |
| emit | +"START ${jname}" | ++ | + |
| --- forJson | +|||
| forJson | +${forJsonFileName} | ++ | + |
| emit | +jname | ++ | + |
| endForJson | ++ | + | + |
| emit | +"INTERMISSION ${jname}" | ++ | + |
| --- load a varset | +|||
| loadJsonVars | +${forJsonFileName} | +jname == "dogbert" | ++ |
| emit | +"END ${jname}" | ++ | + |
| --- check results | +|||
| assertEmitted | +"START ${commands}quot; + "{jname}~dilbert~dogbert~wally~INTERMISSION ${commands}quot; + "{jname}~END dogbert" | ++ | + |
| === Error validations | +|||
| -!- | +|||
| expectError | +"Requires a JSON file path or URL" | ++ | + |
| loadJsonVars | ++ | + | + |
| -!- | +|||
| expectError | +"Multiple JSON objects are not valid for this command" | ++ | + |
| loadJsonVars | +${forJsonFileName} | ++ | + |
| -!- | +|||
| expectError | +'"flubber" is not a boolean expression' | ++ | + |
| loadJsonVars | +${forJsonFileName} | +"flubber" | ++ |
| Test case: forxml | |||
| if | +globalContext.onServer === true | ++ | + |
| store | +../data/forxml.xml | +forXmlFileName | ++ |
| else | ++ | + | + |
| store | +data/forxml.xml | +forXmlFileName | ++ |
| endIf | ++ | + | + |
| resetEmitted | ++ | + | + |
| deleteVars | +xname | ++ | + |
| emit | +"START ${xname}" | ++ | + |
| --- forXml | +|||
| forXml | +${forXmlFileName} | ++ | + |
| emit | +xname | ++ | + |
| endForXml | ++ | + | + |
| emit | +"INTERMISSION ${xname}" | ++ | + |
| --- load a varset | +|||
| loadXmlVars | +${forXmlFileName} | +xname == "dogbert" | ++ |
| emit | +"END ${xname}" | ++ | + |
| --- check results | +|||
| assertEmitted | +"START ${commands}quot; + "{xname}~dilbert~dogbert~wally~INTERMISSION ${commands}quot; + "{xname}~END dogbert" | ++ | + |
| loadXmlVars | +${forXmlFileName} | +xname == "dogbert" | ++ |
| === Error validations | +|||
| -!- | +|||
| expectError | +"Requires an XML file path or URL" | ++ | + |
| loadXmlVars | ++ | + | + |
| -!- | +|||
| expectError | +"Multiple XML elements are not valid for this command" | ++ | + |
| loadXmlVars | +${forXmlFileName} | ++ | + |
| -!- | +|||
| expectError | +'"flubber" is not a boolean expression' | ++ | + |
| loadXmlVars | +${forXmlFileName} | +"flubber" | ++ |
| Test case: continue-break 1 | |||
| resetEmitted | ++ | + | + |
| deleteVars | +f | ++ | + |
| for | +f=3; f <= 9; f++ | ++ | + |
| continue | +f == 6 | ++ | + |
| if | +f > 6 | ++ | + |
| if | +f == 7 | ++ | + |
| continue | ++ | + | + |
| else | ++ | + | + |
| break | ++ | + | + |
| endIf | ++ | + | + |
| endIf | ++ | + | + |
| emit | +"iter=${f}" | ++ | + |
| endFor | ++ | + | + |
| --- check results | +|||
| assertEmitted | +"iter=3~iter=4~iter=5" | ++ | + |
| Test case: continue-break 2 | |||
| resetEmitted | ++ | + | + |
| store | +0 | +i | ++ |
| while | +i++ < 10 | ++ | + |
| continue | +i==3 | ++ | + |
| break | +i==5 | ++ | + |
| emit | +"iter=${i}" | ++ | + |
| endWhile | ++ | + | + |
| --- check results | +|||
| assertEmitted | +"iter=1~iter=2~iter=4" | ++ | + |
| Test case: continue-break 3 | |||
| resetEmitted | ++ | + | + |
| foreach | +fe | +"dilbert","dogbert","wally" | ++ |
| continue | +fe=="dogbert" | ++ | + |
| break | +fe=="wally" | ++ | + |
| emit | +"iter=${fe}" | ++ | + |
| endForeach | ++ | + | + |
| --- check results | +|||
| assertEmitted | +"iter=dilbert" | ++ | + |
| Test case: continue-break 4 | |||
| resetEmitted | ++ | + | + |
| if | +globalContext.onServer === true | ++ | + |
| store | +../data/forxml.xml | +forXmlFileName | ++ |
| else | ++ | + | + |
| store | +data/forxml.xml | +forXmlFileName | ++ |
| endIf | ++ | + | + |
| forXml | +${forXmlFileName} | ++ | + |
| continue | +xname=="dogbert" | ++ | + |
| break | +xname=="wally" | ++ | + |
| emit | +"iter=${xname}" | ++ | + |
| endForXml | ++ | + | + |
| --- check results | +|||
| assertEmitted | +"iter=dilbert" | ++ | + |
| Test case: nested-loops | |||
| resetEmitted | ++ | + | + |
| deleteVars | +i, n, uname | ++ | + |
| startTimer | ++ | + | + |
| store | +2 | +i | ++ |
| emit | +"START ${i}" | ++ | + |
| while | +i > 0 | ++ | + |
| emit | +"while=${i}" | ++ | + |
| foreach | +uname | +"dilbert", "dogbert" | ++ |
| emit | +"foreach=${uname}" | ++ | + |
| for | +n = 2; n <=3; n++ | ++ | + |
| emit | +"FOR=${n}" | ++ | + |
| for | +n = 7; n <= 8; n++ | ++ | + |
| emit | +"for=${n}" | ++ | + |
| endFor | ++ | + | + |
| endFor | ++ | + | + |
| emit | +"endFor ${n}" | ++ | + |
| endForeach | ++ | + | + |
| storeEval | +${i}-1 | +i | ++ |
| endWhile | ++ | + | + |
| emit | +"END ${i}" | ++ | + |
| timerElapsed | ++ | + | + |
| --- check results | +|||
| assertEmitted | +"START 2~while=2~foreach=dilbert~FOR=2~for=7~for=8~FOR=3~for=7~for=8~endFor ${n}~foreach=dogbert~FOR=2~for=7~for=8~FOR=3~for=7~for=8~endFor ${n}~while=1~foreach=dilbert~FOR=2~for=7~for=8~FOR=3~for=7~for=8~endFor ${n}~foreach=dogbert~FOR=2~for=7~for=8~FOR=3~for=7~for=8~endFor ${n}~END 2" | ++ | + |
| Test case: function | |||
| deleteVars | +sname, srole | ++ | + |
| assertEval | +"START ${sname} ${srole}" === "START ${commands}quot; + "{sname} ${commands}quot; + "{srole}" | +true | ++ |
| --- first line | +|||
| call | +doSomething | +sname = "dilbert,Q", srole = "goof" | ++ |
| assertEval | +"${_result}" === "sname=dilbert,Q,srole=goof" | +true | ++ |
| deleteVars | +sname, srole | ++ | + |
| === | +|||
| function | +doSomething | +sname | ++ |
| return | +"sname=${sname},srole=${srole}" | ++ | + |
| endFunction | +doSomething | ++ | + |
| === | +|||
| deleteVars | +sname, srole | ++ | + |
| call | +doSomething | +sname = "dogbert", srole = "woof" | ++ |
| assertEval | +"${_result}" === "sname=dogbert,srole=woof" | +true | ++ |
| deleteVars | +sname, srole | ++ | + |
| call | +doSomething | +sname = "ratbert", srole = "squeak" | ++ |
| assertEval | +"${_result}" === "sname=ratbert,srole=squeak" | +true | ++ |
| deleteVars | +sname, srole | ++ | + |
| --- | +|||
| foreach | +sname | +"asok", "alice" | ++ |
| call | +doSomething | +sname = sname, srole = "super=user" | ++ |
| assertEval | +"${_result}" === "sname=${sname},srole=super=user" | +true | ++ |
| deleteVars | +sname, srole | ++ | + |
| endForeach | ++ | + | + |
| assertEval | +"DONE ${sname} ${srole}" === "DONE ${commands}quot; + "{sname} ${commands}quot; + "{srole}" | +true | ++ |
| === Error validations | +|||
| -!- | +|||
| expectError | +"Function does not exist: NONEXISTENT" | ++ | + |
| call | +NONEXISTENT | ++ | + |
| === deprecated script commands | +|||
| deleteVars | +sname, srole | ++ | + |
| script | +doDeprecated | +sname | ++ |
| return | +"sname=${sname},srole=${srole}" | ++ | + |
| endScript | +doDeprecated | ++ | + |
| call | +doDeprecated | +sname = "wally", srole = "lazy" | ++ |
| assertEval | +"${_result}" === "sname=wally,srole=lazy" | +true | ++ |
| deleteVars | +sname, srole | ++ | + |
| Test case: function-recursive | |||
| resetEmitted | ++ | + | + |
| deleteVars | +degree, n, _result, ud | ++ | + |
| store | +7 | +degree | ++ |
| startTimer | ++ | factorial ${degree} | ++ |
| call | +fac | +n=degree | ++ |
| timerElapsed | ++ | + | + |
| emit | +degree + "!=" + _result | ++ | + |
| === | +|||
| --- recursive factorial | +|||
| function | +fac | +n | ++ |
| if | +n <= 1 | ++ | + |
| return | +1 | ++ | + |
| else | ++ | + | + |
| call | +fac | +n = n-1 | ++ |
| emit | +_result | ++ | + |
| return | +n * _result | ++ | + |
| endIf | ++ | + | + |
| endFunction | ++ | + | + |
| === | +|||
| --- mutual recursive | +|||
| function | +uno | ++ | + |
| emit | +"UNO" | ++ | + |
| storeEval | +${ud}-1 | +ud | ++ |
| if | +ud > 0 | ++ | + |
| call | +due | ++ | + |
| endIf | ++ | + | + |
| endFunction | +uno | ++ | + |
| --- | +|||
| function | +due | ++ | + |
| emit | +"DUE" | ++ | + |
| storeEval | +${ud}-1 | +ud | ++ |
| if | +ud > 0 | ++ | + |
| call | +uno | ++ | + |
| endIf | ++ | + | + |
| endFunction | +due | ++ | + |
| --- | +|||
| store | +5 | +ud | ++ |
| call | +uno | ++ | + |
| === | +|||
| assertEmitted | +"1~2~6~24~120~720~7!=5040~UNO~DUE~UNO~DUE~UNO" | ++ | + |
| Test case: issue-2-function | |||
| function | +xyz | ++ | + |
| log | +'here' | ++ | + |
| endFunction | ++ | + | + |
| call | +xyz | ++ | + |
| Test case: exitTest - base case | |||
| resetEmitted | ++ | + | + |
| exitTest | ++ | + | + |
| throw | +"shouldn't happen" | ++ | + |
| Test case: exitTest - from within a loop | |||
| -- from within a loop | +|||
| for | +i=0; i < 5; i++ | ++ | + |
| if | +i == 3 | ++ | + |
| exitTest | ++ | + | + |
| endIf | ++ | + | + |
| if | +i === 3 | ++ | + |
| throw | +"This test should exit when the increment gets to 3, and this should never be thrown." | ++ | + |
| endIf | ++ | + | + |
| endFor | ++ | + | + |
| Test case: exitTest - from within a function | |||
| -- from within a function | +|||
| call | +doSubExit | ++ | + |
| throw | +"shouldn't happen" | ++ | + |
| function | +doSubExit | ++ | + |
| exitTest | ++ | + | + |
| endFunction | +doSubExit | ++ | + |
| Test case: GlobalFunctions | |||
| getEval | +globalStoredVars = {}; | ++ | + |
| function | +setGlobalVar | ++ | + |
| getEval | +globalStoredVars.aGlobalVar = "set"; | ++ | + |
| endFunction | ++ | + | + |
| Test case: CallGlobalFunction | |||
| getEval | +globalStoredVars.aGlobalVar = "reset"; | ++ | + |
| assertNotEval | +globalStoredVars.aGlobalVar; | +set | ++ |
| assertEval | +globalStoredVars.aGlobalVar; | +reset | ++ |
| call | +GlobalFunctions.setGlobalVar | ++ | + |
| assertEval | +globalStoredVars.aGlobalVar; | +set | ++ |
| Test case: DefineFunctionParameters - Base | |||
| store | +original | +x | ++ |
| store | +original | +y | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| function | +bob | +x,y | ++ |
| assertEval | +"${x}" === "overwritten" | +true | ++ |
| assertEval | +storedVars.y === undefined | +true | ++ |
| endFunction | ++ | + | + |
| call | +bob | +x="overwritten" | ++ |
| assertEval | +"${x}" === "overwritten" | +false | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +storedVars.y === undefined | +false | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| Test case: DefineFunctionParameters - With Default Values | |||
| store | +original | +x | ++ |
| store | +original | +y | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| check that x and y do not leak outside of function scope | +|||
| function | +leakTest | +x="fn default x",y="fn default y" | ++ |
| store | +overwritten | +x | ++ |
| store | +overwritten | +y | ++ |
| endFunction | ++ | + | + |
| check that x and y both take default values when unspecified, but only in function scope | +|||
| function | +defaultsTest | +x="fn default x",y="fn default y" | ++ |
| assertEval | +${x} === "fn default x" | +true | ++ |
| store | +"overwritten" | +x | ++ |
| assertEval | +${x} === "overwritten" | +true | ++ |
| assertEval | +${y} === "fn default y" | +true | ++ |
| store | +"overwritten" | +y | ++ |
| assertEval | +${y} === "overwritten" | +true | ++ |
| endFunction | ++ | + | + |
| defaultsTest 00 | +|||
| call | +defaultsTest | ++ | + |
| leakTest 00 | +|||
| call | +leakTest | ++ | + |
| assertEval | +"${x}" === "fn default x" | +false | ++ |
| assertEval | +"${x}" === "overwritten" | +false | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +"${y}" === "fn default y" | +false | ++ |
| assertEval | +"${y}" === "overwritten" | +false | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| leakTest 01 | +|||
| call | +leakTest | +y = "overwritten" | ++ |
| assertEval | +"${x}" === "fn default x" | +false | ++ |
| assertEval | +"${x}" === "overwritten" | +false | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +"${y}" === "fn default y" | +false | ++ |
| assertEval | +"${y}" === "overwritten" | +false | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| leakTest 10 | +|||
| call | +leakTest | +x = "overwritten" | ++ |
| assertEval | +"${x}" === "fn default x" | +false | ++ |
| assertEval | +"${x}" === "overwritten" | +false | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +"${y}" === "fn default y" | +false | ++ |
| assertEval | +"${y}" === "overwritten" | +false | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| leakTest 11 | +|||
| call | +leakTest | +x = "overwritten", y = "overwritten" | ++ |
| assertEval | +"${x}" === "fn default x" | +false | ++ |
| assertEval | +"${x}" === "overwritten" | +false | ++ |
| assertEval | +"${x}" === "original"; | +true | ++ |
| assertEval | +"${y}" === "fn default y" | +false | ++ |
| assertEval | +"${y}" === "overwritten" | +false | ++ |
| assertEval | +"${y}" === "original"; | +true | ++ |
| Test case: StoreLocal - Function Scope | |||
| setting a local variable from function scope | +|||
| function | +blockScopeVars | ++ | + |
| storeLocal | +this is stored locally | +l | ++ |
| local variables aren't put onto the global variable object | +|||
| assertEval | +storedVarsGlobal.l === "this is stored locally" | +false | ++ |
| local variables will be accessible through stored vars, | +|||
| block vars, and ${} notation as long as they're in scope. | +|||
| assertEval | +storedVars.l === "this is stored locally" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored locally" | +true | ++ |
| assertEval | +"${l}" === "this is stored locally" | +true | ++ |
| endFunction | ++ | + | + |
| local variables must not persist after exiting scope | +|||
| getEval | +storedVarsGlobal.l = null; | ++ | + |
| getEval | +storedVars.l = null; | ++ | + |
| assertEval | +storedVars.l === null; | +true | ++ |
| assertEval | +storedVarsGlobal.l === null; | +true | ++ |
| call | +blockScopeVars | ++ | + |
| assertEval | +storedVarsGlobal.l === "this is stored locally" | +false | ++ |
| assertEval | +storedVars.l === "this is stored locally" | +false | ++ |
| assertEval | +storedVarsLocal.l === "this is stored locally" | +false | ++ |
| assertEval | +"${l}" === "this is stored locally" | +false | ++ |
| Test case: StoreGlobal - Function Scope | |||
| setting a global variable from function scope | +|||
| function | +blockScopeVars | ++ | + |
| storeGlobal | +this is stored globally | +g | ++ |
| global variables should exist everywhere | +|||
| assertEval | +storedVarsGlobal.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVars.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVarsLocal.g === "this is stored globally" | +true | ++ |
| assertEval | +"${g}" === "this is stored globally" | +true | ++ |
| endFunction | ++ | + | + |
| global variables must persist after exiting scope | +|||
| getEval | +storedVarsGlobal.g = null; | ++ | + |
| assertEval | +storedVarsGlobal.g === null; | +true | ++ |
| call | +blockScopeVars | ++ | + |
| assertEval | +storedVarsGlobal.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVars.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVarsLocal.g === "this is stored globally" | +true | ++ |
| assertEval | +"${g}" === "this is stored globally" | +true | ++ |
| Test case: StoreGlobal - While Scope | |||
| clearing any values from previous tests | +|||
| getEval | +storedVarsGlobal.g = null; | ++ | + |
| assertEval | +storedVarsGlobal.g === null; | +true | ++ |
| store | +1 | +i | ++ |
| setting a global variable from while scope | +|||
| while | +i > 0 | ++ | + |
| store | +0 | +i | ++ |
| storeGlobal | +this is stored globally | +g | ++ |
| global variables should exist everywhere | +|||
| assertEval | +storedVarsGlobal.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVars.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVarsLocal.g === "this is stored globally" | +true | ++ |
| assertEval | +"${g}" === "this is stored globally" | +true | ++ |
| endWhile | ++ | + | + |
| global variables must persist after exiting scope | +|||
| assertEval | +storedVarsGlobal.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVars.g === "this is stored globally" | +true | ++ |
| assertEval | +storedVarsLocal.g === "this is stored globally" | +true | ++ |
| assertEval | +"${g}" === "this is stored globally" | +true | ++ |
| Test case: StoreLocal - While Scope | |||
| clearing any values from previous tests | +|||
| getEval | +storedVarsGlobal.l = null; | ++ | + |
| getEval | +storedVars.l = null; | ++ | + |
| assertEval | +storedVars.l === null; | +true | ++ |
| assertEval | +storedVarsGlobal.l === null; | +true | ++ |
| store | +1 | +i | ++ |
| setting a local variable from while scope | +|||
| while | +i > 0 | ++ | + |
| store | +0 | +i | ++ |
| storeLocal | +this is stored locally | +l | ++ |
| local variables aren't put onto the global variable object | +|||
| assertEval | +storedVarsGlobal.l === "this is stored locally" | +false | ++ |
| local variables will be accessible through stored vars, | +|||
| block vars, and ${} notation as long as they're in scope. | +|||
| assertEval | +storedVars.l === "this is stored locally" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored locally" | +true | ++ |
| assertEval | +"${l}" === "this is stored locally" | +true | ++ |
| endWhile | ++ | + | + |
| local variables must not persist after exiting scope | +|||
| assertEval | +storedVarsGlobal.l === "this is stored locally" | +false | ++ |
| assertEval | +storedVars.l === "this is stored locally" | +false | ++ |
| assertEval | +storedVarsLocal.l === "this is stored locally" | +false | ++ |
| assertEval | +"${l}" === "this is stored locally" | +false | ++ |
| Test case: Store - Behaves as StoreLocal | |||
| setting a local variable from function scope | +|||
| function | +blockScopeVars | ++ | + |
| store | +this is stored locally | +l | ++ |
| local variables aren't put onto the global variable object | +|||
| assertEval | +storedVarsGlobal.l === "this is stored locally" | +false | ++ |
| local variables will be accessible through stored vars, | +|||
| block vars, and ${} notation as long as they're in scope. | +|||
| assertEval | +storedVars.l === "this is stored locally" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored locally" | +true | ++ |
| assertEval | +"${l}" === "this is stored locally" | +true | ++ |
| endFunction | ++ | + | + |
| local variables must not persist after exiting scope | +|||
| getEval | +storedVarsGlobal.l = null; | ++ | + |
| getEval | +storedVars.l = null; | ++ | + |
| assertEval | +storedVars.l === null; | +true | ++ |
| assertEval | +storedVarsGlobal.l === null; | +true | ++ |
| call | +blockScopeVars | ++ | + |
| assertEval | +storedVarsGlobal.l === "this is stored locally" | +false | ++ |
| assertEval | +storedVars.l === "this is stored locally" | +false | ++ |
| assertEval | +storedVarsLocal.l === "this is stored locally" | +false | ++ |
| assertEval | +"${l}" === "this is stored locally" | +false | ++ |
| Test case: Function - Can Return Value | |||
| function | +returnsValue | ++ | + |
| return | +"banana" | ++ | + |
| endFunction | ++ | + | + |
| call | +returnsValue | ++ | + |
| assertEval | +"${_result}" === "banana" | +true | ++ |
| Test case: StoreAt - Function Scope Nesting | |||
| function for setting a variable at it's location / ancestor / parent | +|||
| function | +storel | ++ | + |
| storeAt | +this ends up global | +notDefined | ++ |
| storeAt | +this is stored in an ancestor | +l | ++ |
| storeAt only makes global vars if it can't find a definition in preceeding scopes | +|||
| assertEval | +storedVarsGlobal.notDefined === "this ends up global" | +true | ++ |
| assertEval | +storedVarsGlobal.l === "this is stored in an ancestor" | +false | ++ |
| storeAt makes the variables available in parent scopes so | +|||
| they're visible as if they were local. | +|||
| block vars, and ${} notation work transparently. | +|||
| assertEval | +storedVars.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +"${l}" === "this is stored in an ancestor" | +true | ++ |
| endFunction | ++ | + | + |
| storeAt will set the value of a named variable in a parent scope | +|||
| getEval | +storedVarsGlobal.notDefined = null | ++ | + |
| assertEval | +storedVarsGlobal.notDefined === null | +true | ++ |
| getEval | +storedVarsGlobal.l = null; | ++ | + |
| assertEval | +storedVarsGlobal.l === null; | +true | ++ |
| storeLocal | +exists in parent | +l | ++ |
| assertEval | +storedVars.l === "exists in parent"; | +true | ++ |
| call | +storel | ++ | + |
| when defined in a parent scope, the variable will not bubble up to global scope | +|||
| assertEval | +storedVarsGlobal.notDefined === "this ends up global" | +true | ++ |
| assertEval | +storedVarsGlobal.l === "this is stored in an ancestor" | +false | ++ |
| when defined in a parent scope, the nearest ancestor catches the new value for the variable | +|||
| assertEval | +storedVars.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +"${l}" === "this is stored in an ancestor" | +true | ++ |
| Test case: StoreAt - While Scope Nesting | |||
| storeAt will set the value of a named variable in a parent scope | +|||
| getEval | +storedVarsGlobal.notDefined = null | ++ | + |
| assertEval | +storedVarsGlobal.notDefined === null | +true | ++ |
| getEval | +storedVarsGlobal.l = null; | ++ | + |
| assertEval | +storedVarsGlobal.l === null; | +true | ++ |
| storeLocal | +exists in parent | +l | ++ |
| assertEval | +storedVars.l === "exists in parent"; | +true | ++ |
| while block setting a variable at it's location / ancestor / parent | +|||
| storeLocal | +3 | +x | ++ |
| while | +x !== 0 | ++ | + |
| storeAt | +this ends up global | +notDefined | ++ |
| storeAt | +this is stored in an ancestor | +l | ++ |
| storeAt only makes global vars if it can't find a definition in preceeding scopes | +|||
| assertEval | +storedVarsGlobal.notDefined === "this ends up global" | +true | ++ |
| assertEval | +storedVarsGlobal.l === "this is stored in an ancestor" | +false | ++ |
| storeAt makes the variables available in parent scopes so | +|||
| they're visible as if they were local. | +|||
| block vars, and ${} notation work transparently. | +|||
| assertEval | +storedVars.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +"${l}" === "this is stored in an ancestor" | +true | ++ |
| storeEvalLocal | +x -= 1 | ++ | + |
| endWhile | ++ | + | + |
| deleteVar | +x | ++ | + |
| when defined in a parent scope, the variable will not bubble up to global scope | +|||
| assertEval | +storedVarsGlobal.notDefined === "this ends up global" | +true | ++ |
| assertEval | +storedVarsGlobal.l === "this is stored in an ancestor" | +false | ++ |
| when defined in a parent scope, the nearest ancestor catches the new value for the variable | +|||
| assertEval | +storedVars.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +storedVarsLocal.l === "this is stored in an ancestor" | +true | ++ |
| assertEval | +"${l}" === "this is stored in an ancestor" | +true | ++ |
| Test case: sendkeys keys are preserved | |||
| assertEval | +"KEY_ENTER" in storedVars | +true | ++ |
| assertEval | +"KEY_TAB" in storedVars | +true | ++ |
| assertEval | +"KEY_BACKSPACE" in storedVars | +true | ++ |