How can I check multiple expressions in one Matcher fragment?
For example:
class Foo extends Specification {
"Retrieving open issues" should {
"return expected properties with expected data" in {
val issue = Bar.openIssues.head
issue must not beNull
issue.number must beEqualTo(1)
issue.state must beEqualTo("open")
issue.title must beEqualTo("first issue")
}
}
}
Gives error
[error] type mismatch;
[error] found : Int
[error] required: org.specs2.matcher.Matcher[Issue]
[error] issue.number must beEqualTo(1)
Eric references a "classical" type inference issue in this comment, but couldn't find an answer.
The problem lies in this line:
issue must not beNull
Because it is written in operator notation the compiler must infer dots and parentheses at the right position. Following the rule that obj meth arg is the same as obj.meth(arg) this line is interpreted as:
issue.must(not).beNull<missing_arg>
beNull is a member called on the returned value of issue.must(not). The compiler follows the rules of operator notation and treats it as meth while issue.must(not) is treated as obj. Because operator notation always requires that a call must have the form obj meth arg, in the above example the compiler is hold to throw an error because of invalid syntax. But it doesn't do it since there are two further rules:
The white space that separates the identifiers in operator notation must not only contain spaces or tabs, it can also contain a single(!) new line sign.
If no arg can be found an empty argument list is inserted implicitly.
Because of (1), the compiler treats the next line as arg:
issue.must(not).beNull(
issue.number).must(beEqualTo(1))
This is not how the code should be interpreted. To solve the problem it is possible to enclose the whole expression in parentheses:
(issue must not beNull)
or to separate the lines by an empty line:
issue must not beNull
issue.number must beEqualTo(1)
Both solutions work because of (2) the compiler can insert an empty argument list.
Note: If (2) must be applied this is also called a postfix operator. In 2.10 they treat a warning because - as one can see with this question - they can lead to tricky behavior.
Related
I am trying to fix a bug in the Form Painter which is related to the VBDKR-WAERK. The problem is as shown in the screenshot below:
So in place of VBDKR-WAERK should be EUR. The code in Form painter for this part is:
&VBDKR-ZTERM_TX1(IC)&
&'(='SKONTOWERT1(ICZ)' VBDKR-WAERK&)'&
&VBDKR-ZTERM_TX2(IC)&
&'(='SKONTOWERT2(ICZ)' VBDKR-WAERK&)'&
&VBDKR-ZTERM_TX3(IC)&
SKONTOWERT1 and SKONTOWERT2 are type KOMVD-KWERT.
May anyone know what the problem may be?
Please do tell me if you need additional information.
Thank you all in advance!
Field names in SAPScript always have to be entered with leading and closing '&':
VBDKR-WAERK& => &VBDKR-WAERK&
&VBDKR-ZTERM_TX1(IC)&
&'(='SKONTOWERT1(ICZ)' &VBDKR-WAERK&)'&
&VBDKR-ZTERM_TX2(IC)&
&'(='SKONTOWERT2(ICZ)' &VBDKR-WAERK&)'&
&VBDKR-ZTERM_TX3(IC)&
Although the question is not about Smart Forms, I just saw that SAPScript and Smart Forms interpret differently the notation &'pre-text'symbol'post-text'&. SAPScript accepts symbols in pre-text and post-text, but Smart Forms doesn't (with &'(='SKONTOWERT1(ICZ)' &VBDKR-WAERK&)'&, I get the exception FORMATTING_ERROR, message ID SSFCOMPOSER, message number 308, message "Fields within fields are not allowed (SKONTOWERT1).").
This notation works in both technologies:
(=&SKONTOWERT1(ICZ)& &VBDKR-WAERK&)
meaning
Text "(="
followed by variable/symbol SKONTOWERT1 (with ICZ being 3 individual characters each meaning respectively initial value (zero) not output, compress spaces, omit leading zeroes)
followed by one space
followed by variable/symbol VBDKR-WAERK
followed by text ")"
I read this
But when i'm passing string value in the variable at that time i'm getting error
Code :
type(${value}).__name__
Error:
Evaluating expression 'type(Robot).__name__' failed: NameError: name 'Robot' is not defined
String value converting as a variable
Please help me.
You should remove brackets {} around value and leave only $value.
Update to comment:
Robotframework treats everything as string unless you explicitly convert it to other datatype.
${value_str} Set Variable 4
${value_number} Convert To Number ${value_str}
${type1} Evaluate type($value_str).__name__
${type2} Evaluate type($value_number).__name__
Log ${type1}
Log ${type2}
Experimenting with the language I've found that select is defined in the global scope and its precedence is higher than local variables.
def example(select)
puts select
end
example 3
# Syntax error in eval:3: unexpected token: end (expecting when, else or end)
So experimenting with select step by step I get this:
select 1 end
# Syntax error in eval:3: unexpected token: end (expecting when, else or end)
and then
select when 1 end
# Syntax error in eval:1: invalid select when expression: must be an assignment or call
then
select when x = 1 end
# Syntax error in eval:1: invalid select when expression: must be an assignment or call
then
select when x
# Syntax error in eval:1: unexpected token: EOF (expecting ',', ';' or '
I'll skip ahead a few steps as you should have an idea of how I've come to my question…
select when x;
else y
end
# Error in line 1: undefined local variable or method 'x_select_action'
and lastly
x_select_action = 4
select when x;
else y
end
# Error in line 3: undefined method 'x_select_action' (If you declared 'x_select_action' in a suffix if, declare it in a regular if for this to work. If the variable was declared in a macro it's not visible outside it)
So there is this keyword in the language which precedes local variables precedence and I don't know what it's for. But apparently it looks for x_select_action when x is given as a when clause. What is this select for and how is it meant to be used?
Searching online I see select defined on Enumerable, Hash, Channel, and Array… but at first glance these don't seem to be it.
Thanks for the help!
It's similar to Go's select: https://tour.golang.org/concurrency/5
But it still needs some tweaks to be finished, that's why there are no docs about it yet.
I am working with an application that receives parameters like a ":" separated string as node ID and a flow name that may contain several special characters. When I want to parse the arguments an error is triggered due to some issues with special characters like *. This is an example input:
python flowapp.py --remove 00:00:02:84:75:e2:95:42 UDP*node-3_to_node-4*dp9000__#node-1
Here is the code I am using to parse option "--remove" :
parser.add_argument("-r","--remove",help="remove the specified flow\
entry from a given node",nargs='2')
When I execute the app I get the following errors:
...
start_index = consume_optional(start_index)
File "/usr/lib/python2.7/argparse.py", line 1858, in consume_optional
arg_count = match_argument(action, selected_patterns)
File "/usr/lib/python2.7/argparse.py", line 2011, in _match_argument
nargs_pattern = self._get_nargs_pattern(action)
File "/usr/lib/python2.7/argparse.py", line 2176, in _get_nargs_pattern
nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
TypeError: can't multiply sequence by non-int of type 'str'
Is there a way to tell python's argparser to interpret characters like -, * or # as special characters and not "math" operators?
The problem isn't with the special characters. The sys.argv will be something like:
['flowapp.py', '--remove', '00:00:02:84:75:e2:95:42', 'UDP*node-3_to_node-4*dp9000__#node-1']
which argparse should have no problems handling.
The problem is with the string argument to nargs:
parser.add_argument("-r","--remove",...,nargs='2')
As part of parsing it constructs an argument matching pattern, which depends on the nargs value:
nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
TypeError: can't multiply sequence by non-int of type 'str'
If nargs is one of the special values like *, it must be an integer. You gave it a string.
parser.add_argument("-r","--remove",...,nargs=2)
In other versions of argparse, you might get a different error:
ValueError: length of metavar tuple does not match nargs
But it's the same issue.
What I have is following:
<xsl:variable name="myvar" select=".//spss:category[((not #varName) or #varName=$colVarName) and #text=$series]/spss:cell/#text"/>
What it should do is select the text of the spss:cell's text-Attribute as long as it is a child of a spss:category that has
either a varName Attribute with a value equal to $colVarName
OR no varName Attribute at all
What is happening is following error message (sorry translating here, so just the gist of it):
Expected Token ')'. Found Token '#'.
.//spss:category[((not -->#<-- varName) or #varName=$colVarName...
Problem Solved! (See below)
OK, I think I found the mistake:
not must be used with parenthesis, so instead of
(not #varName) or #varName=$colVarName
it should have been
not(#varName) or #varName=$colVarName
indeed - not() is a function that returns the boolean opposite of whatever is between the parens. If necessary - it will cast its argument to a boolean. In this case, an empty node set casts automatically to false, so if #varName gives you an empty node set, not(#varName) will be true.