Running Other Scripts and Handlers
Writing other scripts and handlers outside of the main script for your test allows you to create reusable chunks of code, effectively modularizing your test. But, how do you call those scripts and handlers once they're written? This page explains how, and then provides some related commands and functions.
Calling a Local Handler or Script
Calling a Handler or Script as a Command
Syntax:
scriptOrHandlerName {parameters}
To call another handler within your script, simply use the handler name as a command, along with any needed parameters. For example, consider this command:
recordScores 2017, rawScores
If there is a "to" (or "on") handler in the local script for the recordScores
message, this command will run that handler, passing it two parameters.
If there is no local handler for the recordScores
command, but there is a script by that name, that script (meaning, the script's initial handler) will be run, passing it the two parameters. So in either case, to call a handler in the local script, or another script in the same directory, all that is needed is to use that handler or script name as a command.
Calling a Handler or Script as a Function
Syntax:
scriptOrFunctionName ( {parameters} )
Calling a script or handler as a function works the same way: just use the script or handler name as a function name within an expression context (not at the beginning of a line, which would be a command call). For example, consider this function call:
put consolidatedSales("Ohio") into ohioSales
In this case if there is a "to" (or "function") handler in the local script for the consolidatedSales
message, this function call will run that handler, passing it the single parameter value "Ohio". The return value from that handler will be stored in the variable ohioSales
.
If there is no local handler for the consolidatedSales
function, but there is a script by that name, that script (meaning the script's initial handler) will be run, passing it the value "Ohio", and the return value from that script will be stored into ohioSales
.
For the vast majority of cases, this simple approach to calling another script or handler is all that's needed. The command or function call will send a message to the current script which will be handled by a local handler. If there is no local handler for the message, it will be passed to a local script with the same name as the message.
Calling a Handler Within Another Script
Command Syntax:
scriptName . handlerName {parameters}
scriptName 's handlerName {parameters}Function Syntax:
scriptName . handlerName ( {parameters} )
scriptName 's handlerName ( {parameters} )
Occasionally, you may want to call a handler (other than the initial handler) in another script. To do this, the dot or apostrophe-s notation can be used. For example, to call the to recordScores
handler in a script called "FileUtility" as a command, you could use this command:
FileUtility.recordScores 2017, rawScores
Similarly, to call the consolidatedSales
handler in a "BusinessCenter" script as a function, you could do it like this:
put BusinessCenter's consolidatedSales("Ohio") into ohioSales
Other Flow Control Commands and Functions
These lesser used commands and functions allow you to control the execution flow of your test.
Run
Command
Behavior: Calls the scriptName script, or the handlerName handler of that script, as a command. HandlerName is usually just the simple name of a handler without quotes, but may also be given as a quoted literal, or as an expression in parentheses to construct the handler name at run time.
Syntax:
run scriptName {,} {parameters}
run scriptName 's handlerName {parameters}
The run
command is only needed to run a specified script when a simple command as shown above won't work, such as when a full pathname is needed or the script's name contains spaces or other special characters, or when the name of the script to be run is in a variable. The following command will run the script’s initial handler:
run "/tmp/testScript.st"
Parameters may be passed:
run "common/startup" 1200,true,"salvador"
A specific handler other than the script’s initial handler may be called, using 's:
run "common/finance" 's amortize 143000,6.75,360
The run
command may be used with any object, not just a script file:
run account's accrueInterest 30, 4.125
The preceding example is equivalent to:
Tell account to accrueInterest 30, 4.125
Although the run
command provides similar functionality to that of the tell
command, it offers an alternative syntax for running a script, and also gives you the ability to run the initial handler of a script, which the tell
command does not provide. In addition, the run
command runs the script’s initial handler directly, without calling front scripts, back scripts, or helpers.
The run
command also supports calling a handler whose name is dynamic, or comes from a variable or an expression:
run scriptName.(commandName) playerType,loopLocation
In this case, scriptName
and commandName
are both treated as variables that hold the names of the script and handler to be called. This example sends a "command"-type message that can be handled by either a "to" or "on" handler.
Run
Function
Behavior: Calls the initial handler of a script or other object explicitly as a function. This also allows calling a script whose name is generated dynamically at runtime. The run function needs to be called in a way that sends the run message to the target object, such as using dot notation.
Syntax:
object .run( parameters )
{the} run of object {with parameters}
Example:
set doubler to (script:"return 2*param(1)")
put doubler.run(12) -- 24
get ("test" & testNumber).run(value1, value2)
-- call script dynamically
Tell
Command
Behavior: This flow control command changes the message target for any command or function. Ordinarily, when a generic command or function is called, it sends a message to the object whose script is running (the target of the message). If that object has a handler for that message, that handler is executed, otherwise the message is passed along The Message Path. Tell
changes the target for any generic messages sent by the statement
or StatementList
(see Syntax below), so those messages are sent to the defined object
instead. If the object doesn't have a handler for the message, the message is passed along the subsequent message path as usual.
Syntax:
tell object [ to {:} | : ] statementtell object {to} {:}
statementList
end tell
The messages that are sent to the target include:
- command messages from "generic" commands of the form:
commandName {parameters} - function messages that don't have an explicit target:
functionName ( {parameters} )
{the} functionName of parameter
Examples:
The main use of the Tell
flow control command is as an alternative mechanism for calling handlers in specific objects or scripts. For example, to call the recordScores
handler in a script called "FileUtility" as a command, then instead of using this command...
FileUtility.recordScores 2017, rawScores
... you could use Tell
instead, like this:
Tell FileUtility to recordScores 2017, rawScores
Similarly, to call the consolidatedSales
handler in a "BusinessCenter" script as a function, then instead of doing it like this:
put BusinessCenter's consolidatedSales("Ohio") into ohioSales
you could use Tell
instead, like this:
Tell BusinessCenter to put consolidatedSales("Ohio") into ohioSales
Those examples may not add much other than clarifying the intent of the code and making it more readable. The real utility of Tell
comes when using the block form of Tell
to target a number of commands and functions to a specific object, or in cases where the object isn't a script, but is stored in a variable.
Example:
Here is an example that uses the block form of Tell
.
Tell BusinessCenter
put consolidatedSales("Ohio") into ohioSales
put consolidatedSales("Pennsylvania") into pennsylvaniaSales
put consolidatedSales("California") into californiaSales
End Tell
Example:
Here is an example involving a deckofCards
object that is created from a "StandardDeck" script.
set deckOfCards to a new StandardDeck with {jokers:No} -- Set up the test with a standard deck and no jokers
// Use Tell to shuffle a deck of cards and deal two Poker hands:
tell deckOfCards -- Directs the following commands and functions to the deckOfCards object
shuffle -- Shuffle command is sent to DeckOfCards object
put dealCards(5) into pokerHand1 -- Sends the dealCards function message, with a parameter of 5, to the deckOfCards object and stores the output in pokerHand1
put dealCards(5) into pokerHand2 -- Repeats the same as the prior command but stores the output in pokerHand2
end tell
// Print the output to the run window:
put "Hand 1: " & pokerHand1
put "Hand 2: " & pokerHand2