Expecco API
Aus ExpeccoWiki
expecco API
The expecco API provides functions and access to the underlying class library for the use in elementary blocks.
The JavaScript and the Smalltalk API consist of the same functions - both call into the underlying [Smalltalk/X] system, for which extensive documentation is available as [Online Documentation] and as [Class Reference].
Function calls in JavaScript and Smalltalk only differ in their syntax:
| JavaScript | Smalltalk | |
|---|---|---|
| this | self | Current activity |
| this.functionName() | self functionName | Call without arguments |
| this.functionName(arg) | self functionName:arg | One argument call |
| this.namePart1_part2(arg1,arg2) | self namePart1:arg1 part2:arg2 | Two arguments |
| functionName(...) | self functionName... | implizit this/self receiver |
| accessor | self accessor | slot access - implicit this/self send |
All functions are actually implemented in Smalltalk and follow the standard smalltalk naming conventions. The same function names are used for Javascript. As seen above, this scheme works well for functions without or with a single argument, but requires a name translation for functions with more than one argument. This translation is done by the JavaScript compiler by replacing every colon (:) of the Smalltalk name by an underline (_) character, except for the last colon.
In JavaScript, a function-name alone (i.e. without explizit receiver) is translated into a self-send; thus "this.foo()" and "foo()" are equivalent.
Also, for non-argument accessor functions (getters), the empty argument list can be omitted in JavaScript; therefore, "foo" and "this.foo", "foo()" and "this.foo()" are all equivalent.
For example, the JavaScript call:
this.environmentAt("foo")
is written in Smalltalk as:
self environmentAt:'foo'
and, to demonstrate the multi-argument translation rule,
the Smalltalk code:
self environmentAt:'foo' put:1234
is written in JavaScript as:
this.environmentAt_put("foo", 1234)
Syntax
| JavaScript | Smalltalk | Notes |
|---|---|---|
| this | self | |
| rcvr.f () | rcvr f | function call |
| rcvr.f (arg) | rcvr f: arg | with 1 arg |
| rcvr.a_b (arg1, arg2) | rcvr a: arg1 b: arg2 | with 2 args notice the different names of the function "a_b" vs."a:b:" |
| return; | ^ self | without return value |
| return expr; | ^ expr | with return value |
| return from execute; | ^ self | return outer from inner function |
| ; | . | Statement Terminator/Separator |
Syntactic Sugar
The JavaScript syntax is mapped to corresponding Smalltalk library functions as follows:
| if (expr) { .. } | (expr) ifTrue:[ ... ] | |
| if (expr) { .. } else { ... } | (expr) ifTrue:[ ... ] ifFalse:[...] | |
| while (expr) { .. } | [expr] whileTrue:[ ... ] | Notice the square brackets |
| for (expr1;expr2;expr3) { .. } | expr; [expr2] whileTrue:[ ... expr3 ] | |
| try { .. } finally {...} | [...] ensure:[...] | |
| var++ | var := var + 1 | |
| var-- | var := var - 1 |
Operators
| JavaScript | Smalltalk | Notes |
|---|---|---|
| % | \ | modulu operator |
| << | bitShift: | left-shift; negative shift count is right-shift |
| >> | rightShift: | right-shift; negative shift count is left-shift |
Inner Functions in JavaScript
It is possible to create functions within the elementary block's code. This example shows how to do so:
function f(Arg1, Arg2) {
return(Arg1 + Arg2);
}
A function f is created with two arguments (Arg1, Arg2), which returns the sum of both. The function is called like this:
f(3,5)
Inner functions can be used for example to filter specific elements from collections.
Inner functions are first class objects: they can be stored in variables, collections, passed as argument or returned from functions. They can even be passed to other blocks via input- and output pins.
Notice, that there is a difference in the behavior of the return statement between JavaScript inner functions
and Smalltalk blocks: a JavaScript "return" statement inside an inner function returns from that inner function only (whereas a return in Smalltalk always returns from the outer-most method).
o return from the outermost function in JavaScript, use the "return from <fnName>" statement form.
In expecco, where the outermost function is always named "execute", write:
...
return from execute;
...
Inner Functions in Smalltalk (Blocks)
In Smalltalk, inner functions are called "block", and are defined as:
f := [:arg1 :arg2 | arg1 + arg2 ].
This block can be called by sending at a "value:value:" message (one "value:" for each argument):
f value:3 value:5
Blocks without argument are defined as:
f := [ Transcript showCR:'blabla: Euler was great' ].
and invoked with a simple "value" message.
Smalltalk blocks and JavaScript inner functions can be used interchangable - i.e. it is possible to pass a JS inner function to a collection method such as "collect:" or "select:". It is also possible, to pass either via input/output pins to other activities (which is not considered good style, as it could make the program quite hard to understand, if not used with caution).
Notice, that the behavior of the Smalltalk return ("^") is different from a JavaScript return ("return-Statement") inside inner functions. The JavaScript return returns a value from the inner function, whereas the Smalltalk return forces a return from the containing method (the block's "execute" method). The Smalltalk return always behaves like the "return from execute" JavaScript special form.
Example uses for Inner Functions
In Smalltalk, blocks are very often used when enumerating collections. For example, code corresponding to a C# 3.0 collection select (where(x => ...)) is written in Smalltalk as:
|names namesStartingWithA|
names := #( 'Alice' 'Ann' 'Bob' 'Mallory' ).
namesStartingWithA := names select:[:n | n startsWith:'A'].
or in JavaSript as:
var names, namesStartingWithA;
names = [ "Alice" , "Ann" , "Bob" , "Mallory" ];
namesStartingWithA = names.select( function(n) { n.startsWith("A"); } );
To find the first element in a collection, for which some condition is true, use:
|names firstNameContainingAnO|
names := #( 'Alice' 'Ann' 'Bob' 'Mallory' ).
firstNameContainingAnO:= names detect:[:n | n includesString:'o'].
or in JavaSript as:
var names, firstNameContainingAnO;
names = [ "Alice" , "Ann" , "Bob" , "Mallory" ];
firstNameContainingAnO = names.detect( function(n) { n.includesString("o"); } );
For more information on the Smalltalk syntax, see [Smalltalk Basics] in the [Smalltalk Online Tutorial].
Builtin Data Types
An introductionary overview and links to the detailed documentation of individual classes is found in the [Class Documentation] of the [Smalltalk/X online documentation].
Numeric Types
The underlying numeric type implementation supports multiple number represenations. These can be used transparently in mixed-operations, and values are automatically converted as required. For example, the division of two integers returns another integer iff the division does not produce a remainder. Otherwise, a fraction object is returned, if there was a remainder. Although very very rarely required in practice, values can be converted explicitly, via one of the "asXXX" messages, if required:
- asFloat()
- asInteger()
- asFraction()
- asFixedPoint(scale)
Thus, if you want to avoid fractions (why would you?), process the result of an integer division using one of the asFloat(), truncated(), floor(), ceiling() or rounded() functions.
Integer
This represents arbitrary precision integral numbers. Conversion and memory allocation is completely automatic. Thus, you can write:
x = 100.factorial();
to get the huge number:
933262154439441526816992388562667004907159682643816214685929638952175999932299156089 41463976156518286253697920827223758251185210916864000000000000000000000000
Small integer values (<32 bit) are stored more efficiently than large integers - however, the conversion and representation as used by the system is completely transparent and automatic. The same is true for mixed mode arithmetic between small and large integers. [More Info]
Float
Float represents double precision IEEE floating point numbers (64bit). Although seldom needed, conversion to single precision (32bit) and high prevision (80bit) is allowed via the asShortFloat() and asLongFloat() conversion functions. [More Info]
Fraction
Fractions are arbitrary-precision rational numbers. You will get them when dividing two integers and the result is not integral. For example:
1 / 3
returns a fraction result with a numerator of 1 and a denominator of 3. Fractions have the advantage of avoiding rounding errors; thus, when the above fraction is divided by 3, you will get (1/9), which we can multiply by 9 to get the exact 1 (an integer) without any rounding error. Notice that this is typically not the case with Float or Double precision numbers; due to rounding errors on the last bit, you will often get 0.9999999 as a result there.
Fractions automatically reduce themself - therefore, when adding (1/3) + (2/6), you will get (2/3). [More Info]
FixedPoint
FixedPoint numbers are decimals, with a configurable number of post-decimal digits. They are typically used when dealing with money. Like fractions, they avoid rounding errors. However, when printed, they round in their last digit (however, the exact information is always kept for further processing). FixedPoint numbers are perfect to represent money and other fractional data, which must be represented with a fixed number of post-decimal digits. [More Info]
String Types
Strings can come in two flavours, depending on how many bits are required to encode the character's codePoint. In general, UNICODE is used internally as the encoding. However, converters are available to translate into other encodings, such as JIS or ISO8859-x.
String
This is used to represent character strings, where each individual character has a one-byte encoding. I.e. the values are 0..255. [More Info]
Unicode16String
This is used to represent character strings, where at least one character needs a two-byte encoding. I.e. any value is in the range 0x0100 .. 0xFFFF.
Character
Individual characters (as extracted from a string or possibly read from a file) are represented as instances of the Character class. Queries are available to ask the character for its type (isLetter, isDigit etc.) or its encoding (codePoint). [More Info]
Collection Types
An introductionary overview on the collection classes is found in the [Collections Overview] of the [Smalltalk/X online documentation].
Array
Ordered, fixed size, indexed by an integral index starting with 1. Can store any type of object. [More Info]
ByteArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store very small byte-valued unsigned integers (0..255). [More Info]
BitArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store tiny bit-valued unsigned integers (0..1).
BooleanArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store booleans (false..true).
FloatArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store short IEEE floats (32bit). [More Info]
DoubleArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store IEEE doubles (64bit).
IntegerArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 32bit unsigned integer values (0..FFFFFFFF)
SignedIntegerArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 32bit signed integer values (-800000000..7FFFFFFF)
LongIntegerArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 64bit unsigned integer values (0..FFFFFFFFFFFFFF)
SignedLongIntegerArray
Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 64bit signed integer values (-80000000000000000..7FFFFFFFFFFFFFFF)
OrderedCollection
Ordered, variable size, indexed by an integral index starting with 1. Can store any type of object. [More Info]
SortedCollection
Sorts itself, variable size, indexed by an integral index starting with 1. Can store any type of object. By default, sorting is by ascending order. However, the sort order can be arbitrarily changed by setting the sortBlock, a two-argument JS-function or a two-argument Smalltalk block which should return true, if its first argument is to be "considered" smaller within the order. [More Info]
Set
Unordered, variable size, keeps a single reference only, per equal element. Can store any type of object. [More Info]
Bag
Unordered, variable size, keeps a count, per equal element. Can store any type of object.
Dictionary
Unordered, variable size, implements arbitrary key-value mappings. Can store any type of object. Java users will know a subset of the dictionary functionality as "Hashtable". [More Info]
OrderedDictionary
Ordered, variable size, implements arbitrary key-value mappings. Can store any type of object. Being similar to dictionaries, these remember the order by which elements were added.
Queue
Ordered, variable size. Can store any type of object. [More Info]
BTree, AATree
Similar to Dictionaries, these keep their elements in a sorted order, indexed by a key-object. In contrast to Dictionaries, which use hashing, these use a tree-like representation and guarantee both logO worstcase and average runtime. (Dictionaries have a much better average runtime of C, but also a much worse worstcase of O).
Stream Types
An introductionary overview on the stream classes is found in the [Streams Overview] of the [Smalltalk/X online documentation].
FileStream
Provide bytewise or linewise access to the underlying file system. [More Info]
CharacterWriteStream
A special stream usable for mixed single- and multibyte characters (i.e. Unicode).
Socket
Low level access to TCP/IP communication mechanism. [More Info]
Other useful Types
Date
Represents a date. [More Info]
Time
Represents a time-of-day in second resolution. [More Info]
Timestamp (Date and Time)
Represents a timestamp in millisecond resolution. Due to the internal representation (Unix format), only timestamps back to 1.1.1970 can be represented. [More Info]
TimeDuration
Represents an amount of time, to represent time intervals. When reading, a unit-specifier character is allowed to specify milliseconds (ms), seconds (s), minutes (m), hours (h) or days (d). For example, "1h 20s" specifies 1 hour and 20 seconds. [More Info]
Standard Objects
In order for a "well known" environment to be provided to those who know JS, but do not know Smalltalk, mimicri classes (Math) and protocol has been added to the underlying Smalltalk system. This is described below. Notice that this represents only a small fraction (less than 1/100) of the real functionality of the base system. In order to find out more about all existing classes, you should open a class browser and navigate through the system yourself. There is also a more detailed introduction to the basic classes found at [1].
Math
Constants
- E
Euler's constant, the base of the natural logarithm (approximately 2.718)
- LN10
Natural logarithm of 10 (approximately 2.302)
- LN2
Natural logarithm of 2 (approximately 0.693)
- LOG10E
Base 10 logarithm of E (approximately 0.434)
- LOG2E
Base 2 logarithm of E (approximately 1.442)
- PI
Pi (approximately 3.14159)
- SQRT1_2
Square root of 1/2 (approximately 0.707)
- SQRT2
Square root of 2 (approximately 1.414)
Min & Max
- max(number1 , number2)
Returns the largest of 0 to 5 arguments
- min(number1, number2)
Returns the smallest of 0 to 5 arguments
Miscellaneous
- abs(aNumber)
Returns the absolute value of aNumber
- binco(n, k)
Returns the binomial coefficient C(n,k) (n over k, choose k from n)
- ceil(aNumber)
Returns the smallest integer greater than or equal to aNumber
- exp(aNumber)
Returns EaNumber, where aNumber is the argument, and E is Euler's constant, the base of the natural logarithm
- fac(aNumber)
Returns the factorial of aNumber
- floor(aNumber)
Returns the greatest integer less than or equal to aNumber
- gcd(a, b)
Returns the greatest common divisor of a and b
- log10(aNumber)
Returns the log base 10 of aNumber
- log(aNumber)
Returns the log base E of aNumber
- pow(base, exp)
Returns base to the exponent power, that is, baseexp
- random
Returns a pseudo random number between 0 and 1
- round(aNumber)
Returns the value of aNumber rounded to the nearest integer
- sqrt(aNumber)
Returns the square root of aNumber
Trigonometric
- acos(aNumber)
Returns the arccosine (in radians) of aNumber
- asin(aNumber)
Returns the arcsine (in radians) of aNumber
- atan2(x, y)
Returns the arctangent of the quotient of its arguments (in radians)
- atan(aNumber)
Returns the arctangent (in radians) of aNumber
- cos(aNumber)
Returns the cosine of aNumber (given in radians)
- sin(aNumber)
Returns the sine of aNumber (given in radians)
- tan(aNumber)
Returns the tangent of aNumber (given in radians)
Number
Properties
- MAX_VALUE
The largest representable number
- MIN_VALUE
The smallest representable number
- NEGATIVE_INFINITY
Returns the special 'negative infinity' value
- NaN
Returns the special 'not a number' value
- POSITIVE_INFINITY
Returns the special 'positive infinity' value
Methods
- asFloat()
Returns a floating-point version of the receiver object. For example: "1.asFloat()" yields the floating point number: "1.0".
- asInteger()
Returns an integer version of the receiver object (truncating). For example: "1.0.asInteger()" yields the integer number: "1". Alternatives are ceiling(), floor() and rounded().
- ceiling()
For non-integral values, ceiling returns the smallest integer which is larger than the receiver. For integers, the original value is returned. For example: "1.4.ceiling()" yields the integer number: "2", whereas "1.ceiling()" returns "1". See also: floor() and rounded().
- floor()
For non-integral values, floor returns the largest integer which is smaller than the receiver. For integers, the original value is returned. For example: "1.4.floor()" yields the integer number: "1", whereas "1.floor()" returns "1". See also: ceiling() and rounded().
- rounded()
For non-integral values, rounded returns the nearest integer from rounding. For integers, the original value is returned. For example: "1.4.rounded()" yields the integer number: "1", "1.6.rounded()" yields the integer number: "2" and whereas "1.rounded()" returns "1". See also: ceiling() and floor().
- roundTo(r)
Rounds towards the nearest multiple of r. For example, "1.543.roundedTo(0.01)" returns "1.54" and "1.567.roundedTo(0.01)" returns "1.57". See also: ceiling(), floor() and rounded().
- toExponential(nDigits)
Returns a string representing the number in exponential notation, where nDigits is the number of digits to appear after the decimal point
- toExponential(nDigits, nDigitsAfter)
Returns a string representing the number in exponential notation
- toFixed(nDigits)
Returns a string representing the number in fixed notation, where nDigits is the number of digits to appear after the decimal point
Random
- nextBoolean
Randomly returns either true or false
- next
Returns a random number between 0 and 1 (float)
- nextIntegerBetween_and_(min, max)
Returns a random integer between min and max (use 1 and 6, to simulate a dice)
Time / Date
- getDate
Returns the day of the month (1..31)
- getDay
Returns the day of the week (0..6); Sunday is 0
- getFullYear
Returns the year
- getHours
Returns the hours (0..24)
- getMinutes
Returns the minutes (0..60)
- getMonth
Returns the day of the month (1..12)
String
- charAt0(index)
Returns the n'th character, using a 0-based indexing scheme
- charAt1(index)
Returns the n'th character, using a 1-based indexing scheme
- charCodeAt0(index)
Returns the code of the n'th character, using a 0-based indexing scheme
- charCodeAt1(index)
Returns the code of the n'th character, using a 1-based indexing scheme
- indexOf0(aCharacter)
Returns the index of aCharacter, using a 0-based indexing scheme; -1 if not found
- indexOf1(aCharacter)
Returns the index of aCharacter, using a 1-based indexing scheme; 0 if not found
- lastIndexOf0(aCharacter)
Returns the last index of aCharacter, using a 0-based indexing scheme; -1 if not found
- lastIndexOf1(aCharacter)
Returns the last index of aCharacter, using a 1-based indexing scheme; 0 if not found
- quote
Wraps the receiver into quotes ("")
- split(separator)
Splits the string into a collection of substrings using the separator
- substr0(index, count)
Extracts a substring starting at the index with the given length, using a 0-based indexing scheme
- substr1(index, count)
Extracts a substring starting at the index with the given length, using a 1-based indexing scheme
- substring0(index1)
Extracts a substring starting at the index, using a 0-based indexing scheme
- substring0(index1, index2)
Extracts a substring between the given indices, using a 0-based indexing scheme
- substring1(index1)
Extracts a substring starting at the index, using a 1-based indexing scheme
- substring1(index1, index2)
Extracts a substring between the given indices, using a 1-based indexing scheme
- toLowerCase
Returns a copy of the receiver with all chars in lower case
- toUpperCase
Returns a copy of the receiver with all chars in upper case
- trim
Returns a copy of the receiver with all leading and trailing white space removed
- trimLeft
Returns a copy of the receiver with all leading white space removed
- trimRight
Returns a copy of the receiver with all trailing white space removed
Collection (Array)
- concat(aCollection)
Returns a new collection consisting of the concatenation of the receiver and the argument
- every(filterFunction)
Returns true, if "filterFunction" returns true for all elements
- filter(filterFunction)
Selects elements for which "filterFunction" returns true
- forEach(function)
Applies "function" for each element
- join(seperator)
Joins the strings of the receiver into a single string using the separator
- map(function)
Returns a new collection collecting the results of applying "function" to each element in sequence
- pop
Removes and returns the last element of the collection
- push(value)
Adds an element to the end of the collection
- reduce0(filterFunction)
Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 0-based indices to the filter.
- reduce0(filterFunction, initialValue)
Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 0-based indices to the filter.
- reduce1(filterFunction)
Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 1-based indices to the filter.
- reduce1(filterFunction, initialValue)
Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 1-based indices to the filter.
- shift
Removes and returns the first element of the collection
- slice0(index1, index2)
Extracts a subcollection, using a 0-based indexing scheme
- slice1(index1, index2)
Extracts a subcollection, using a 1-based indexing scheme
- some(filterFunction)
Returns true, if "filterFunction" returns true for any element
- unshift(arg)
Adds an element to the beginning of the collection
Transcript
The global variable "Transcript" refers to either the transcript information window (if it is open) or the standard error stream. As such, it implements most of the stream interface functions. Most noteworthy are:
- cr()
Adds a linebreak (i.e. followup text will be shown on the next line)
- show(arg)
Adds a textual representation of the argument, which can be a string, number or any other object.
- showCR(arg)
A combination of show(), followed by a linebreak.
Expecco Objects
Many object are reachable by elementary code (i.e. from within an elementary-coded action's code). A lot of useful and required information can be aquired by consulting these objects. The anchor to all those objects is the "current activity" object.
Current Activity
Within elementary code the activity instance which is executing this piece of code can be accessed via the variable "this" (Smalltalk: "self"). For every executed action, a new activity obejct is created. It is usually alive during the execution only (i.e. it is destroyed and its memory reused automatically, after the block's action has finished). It supports the following functions:
Reporting
- error()
Report a defect (in the test). Stops execution.
- error(infoString)
Report a defect (in the test). Stops execution.
- fail()
Report a failure (in the SUT). Stops execution.
- fail(infoString)
Report a failure (in the SUT). Stops execution.
- inconclusive()
Report an inconclusive test. Stops execution.
- inconclusive(infoString)
Report an inconclusive test. Stops execution.
- success() OBSOLETE - see below
Finishes the current activity with success.
- success(infoString) OBSOLETE - see below
Finishes the current activity with success.
- activitySuccess()
Finishes the current activity with success.
- activitySuccess(infoString)
Finishes the current activity with success.
- pass()
Finishes the current testCase with success.
- pass(infoString)
Finishes the current testCase with success.
Logging
- logData(data)
Adds data to the activity log.
- logDataFile(fileName)
Adds a file attachment to the activity log.
- logError(messageString)
Adds a error message to the activity log.
- logError(messageString, detail)
Adds a error message to the activity log.
- logWarning(messageString)
Adds a warning to the activity log.
- logWarning(messageString, detail)
Adds a warning to the activity log.
- logInfo(messageString)
Adds an info message to the activity log.
- logInfo(messageString, detail)
Adds an info message to the activity log.
- logImageInfo(messageString, image)
Adds an info message with an image (screendump) to the activity log. There is an option in the report generator to include those in the generated pdf-report.
- alert(messageString) (1.8.1)
Adds an warning message to the activity log, and also shows a DialogBox, which has to be confirmed by the operator. The DialogBox and confirmation can be disabled by a settings flag in the "Execution - Log -Settings" dialog.
- warn(messageString) (1.8.1)
Same as alert() (for Smalltalk compatibility).
Notice the similarity and difference between "error()" and "logError()": both actually create a log-data entry, but "error()" stops the execution, whereas "logError()" proceeds (maybe, the naming is a bit confusing here...)
Reflection, Information, Queries and Accessing
- activityCreator()
The triggering activity (i.e. the caller)
- activityProcess()
The thread executing the activity
- blockDescription()
The definition of the activity (i.e. the tree definition item of the action's step)
- environment()
The currently valid environment variables
- environmentAt(anEnvironmentVarName)
The value of an environment variable
- environmentAt_put(anEnvironmentVarName, value)
Changing the value of an environment variable.
- executor()
Returns the current executor.
- inputValueForPin(pinName)
The value of a certain pin
- inventory()
The inventory of the activity
- nameOfStep()
The name of the corresponding step of the activity
- resources()
All resources which have been aquired for the activity (as specified in the resource-definition of the action). Retrieves a collection of Resource objects, as described below.
- resourcesForId(skillId)
Resources which have been aquired for one particular skill-requirement. The argument skillId corresponds to the name as specified in the first column of the resource definition of the action). Notice, that a collection of Resource objects is returned - even if only one resource has been aquired.
- step()
The corresponding step of the activity
Executor Functions
- executorsWorkingDirectory()
Temporary working directory. This is removed after the execution (i.e. useful only for very temporary files, which are generated in an action and read in another)
- testplan()
The currently executed testplan (nil if a block test blocks are executed)
- project()
Project (testsuite or library) in which the test is executed
Resource Functions
- name()
The name of the resource
- skillNamed(nameOrUUID)
Fetch a concrete skill-value of that resource. The argument can be either a skills name, or the functional-UUID of the skill element (in the project tree).
- skillAttributeNamed(name)
Fetch a concrete skill-attribute-value of the resource
Project Functions
- documentation()
The documentation or nil
- functionalId()
A unique ID which defines this testSuite independent of its name (remains constant after change)
- projectsWorkingDirectory()
Project directory - i.a. all attachments. This directory is created when a project file is loaded and is deleted when expecco is closed. Do not use it for permanently needed files.
- modelLanguageStringFor(aString)
translates a string according to the model-language translation table
- versionId()
A unique ID which defines this testSuite in exactly this version. (changed with any edit operation)
Testplan Functions
- documentation()
The documentation or nil
- name()
The name of the Testplan
- tags()
A collection of tags of the testplan
- functionalId()
A unique ID which defines this testplan independent of its name (remains constant after change)
- versionId()
A unique ID which defines this testplan in exactly this version. (changed with any edit operation)
Step Functions
- name()
The name of the Step
- tags()
A collection of tags of the Step
Pin Functions
The input and output pins can be referenced in elementary code by their name. The name references the pin - NOT the passed value.
- datatype()
Returns the data type of the pin (Reflection-API)
Input Pins:
- hasValue()
Returns true if the pin has received a value (important for the trigger conditions ANDConnected and OR)
- hasEnvironmentFreezeValue()
Returns true if the pin has a freezeValue from an environment
- hasFreezeValue()
Returns true if the pin has a freezeValue
- isConnected()
Returns true if the pin is connected (but not frozen)
- value()
Returns the value of the pin. Raises an error if the pin did not receive any value.
- valueIfAbsent(alternativeValue)
Returns the value of a pin or the alternativeValue if the pin did not receive any value.
- valueIfPresent()
Returns the value of a pin or nil if the pin did not receive any value. Similar to "value()", but avoids the exception.
- waitForValue()
The pin has to be a mailbox pin. The execution will be interrupted until the pin receives a value.
- waitForValueWithTimeout(seconds)
Like above, but the execution will only wait for the specified time limit given in seconds. The parameter is typically an integer, but can also be a fraction (1/3) or a floating-point number (0.3).
Output Pins:
- isBuffered()
True if the pin is buffered
- isConnected()
Returns true if the pin is connected
- value(data)
Writes the value.
Examples
Square Root Block
A function, which computes the square root of its input value, could be implemented like that: (the names of the pins are: in and out, their data type is Number):
JavaScript
execute() {
var inValue;
inValue = in.value; // Reading input value
out.value( inValue.sqrt() ); // Writing on output pin
}
Smalltalk
execute
|inValue|
inValue := in value. "/ Reading input value
out value: inValue sqrt. "/ Writing on output pin
Random-Fail Block
A block, which randomly fails (to demonstrate exception handling), could be implemented like:
JavaScript
execute() {
var dice;
dice = Random.nextIntegerBetween_and_(1,6);
if (dice <= 2) {
fail();
}
}
Smalltalk
execute
|dice|
dice := Random nextIntegerBetween:1 and:6.
(dice <= 2) ifTrue:[
self fail.
].
Please note, that besides these direct interfaces with the expecco system described here, you can also use the whole class library of the runtime system. Please check the corresponding Smalltalk/X Documentation as well as the Documentation of the Class APIs.
Here are more examples, using that class library:
Bulk-Data Reading from a File
The following code reads a measurement data block of 100000 floating point values from file. The file was created beforehand by a recorder device, which was triggered by a dll-callout. For the demonstration, the code below does not read its values from input pins. In a more reusable real world application, the size of the file and its fileName should be passed in via input pins, of course.
JavaScript
execute() {
var N; // should be read from an input-pin
var fileName; // should be read from an input-pin
var dataArray;
var fileStream;
N = 100000;
fileName = 'dataFile.dat';
fileStream = fileName.asFilename().readStream();
dataArray = Array.new(N);
for (i=1; i<=N; i++) {
dataArray[i] = fileStream.nextIEEESingle();
}
out.value(dataArray);
}
Smalltalk
execute
|N fileName dataArray fileStream|
N := 100000.
fileName := 'dataFile.dat'.
fileStream := fileName asFilename readStream.
dataArray := (1 to:N) collect:[:i | fileStream nextIEEESingle].
out value:dataArray.
Sending Messages to the Transcript
JavaScript
execute() {
Transcript.showCR("---------------------");
for (var y=1; y<=10; y++) {
for (var x=1; x<=10; x++) {
Transcript.show( x * y );
Transcript.show( " " );
}
Transcript.cr();
}
}
Smalltalk
execute
Transcript showCR:'---------------------'.
1 to:10 do:[:y |
1 to:10 do:[:x |
Transcript show:(x * y); show:' '.
].
Transcript cr.
].
Back to Online Documentation