Dynamic value for an element using property expansion - groovy

Referring property expansion from here
One of the element of the soap request is defined as follows.
<ns:PRODUCTID>${=def list = [12, 13,12];list.join(',')}</ns:PRODUCTID>
And when the request is submitted, it evaluates correctly and sends out the request as below(from the raw request):
<ns:PRODUCTID>12,13,12</ns:PRODUCTID>
However, could not get it working a dynamic value as shown below, i mean it is leading below error
<ns:PRODUCTID>${=def a = (int)(Math.random()*5);def list = [];a.times {list.add((int)(Math.random()*1000))};list.join(',')}</ns:PRODUCTID>
But the same script runs perfectly fine when it is run separately.
Error below:
startup failed:
Script16.groovy: 1: expecting '}', found '' # line 1, column 94.
add((int)(Math.random()*1000))
^
org.codehaus.groovy.syntax.SyntaxException: expecting '}', found '' # line 1, column 94.
at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:139)
at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:107)
at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:236)
at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:163)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:839)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:544)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:520)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:497)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:306)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:287)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:731)
at groovy.lang.GroovyShell.parse(GroovyShell.java:743)
at groovy.lang.GroovyShell.parse(GroovyShell.java:770)
at groovy.lang.GroovyShell.parse(GroovyShell.java:761)
at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.compile(SoapUIGroovyScriptEngine.java:148)
at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:93)
at com.eviware.soapui.model.propertyexpansion.resolvers.EvalPropertyResolver.doEval(EvalPropertyResolver.java:191)
at com.eviware.soapui.model.propertyexpansion.resolvers.EvalPropertyResolver.resolveProperty(EvalPropertyResolver.java:170)
at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expand(PropertyExpander.java:180)
at com.eviware.soapui.model.propertyexpansion.PropertyExpander.expandProperties(PropertyExpander.java:113)
at com.eviware.soapui.impl.wsdl.submit.filters.PropertyExpansionRequestFilter.filterWsdlRequest(PropertyExpansionRequestFilter.java:45)
at com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter.filterAbstractHttpRequest(AbstractRequestFilter.java:37)
at com.eviware.soapui.impl.wsdl.submit.filters.AbstractRequestFilter.filterRequest(AbstractRequestFilter.java:31)
at com.eviware.soapui.impl.wsdl.submit.transports.http.HttpClientRequestTransport.sendRequest(HttpClientRequestTransport.java:184)
at com.eviware.soapui.impl.wsdl.WsdlSubmit.run(WsdlSubmit.java:123)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: Script16.groovy:1:94: expecting '}', found ''
at groovyjarjarantlr.Parser.match(Parser.java:211)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.closableBlock(GroovyRecognizer.java:8620)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.appendedBlock(GroovyRecognizer.java:11397)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.pathElement(GroovyRecognizer.java:11349)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.pathExpression(GroovyRecognizer.java:11464)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.postfixExpression(GroovyRecognizer.java:13175)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.unaryExpressionNotPlusMinus(GroovyRecognizer.java:13144)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.powerExpressionNotPlusMinus(GroovyRecognizer.java:12848)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.multiplicativeExpression(GroovyRecognizer.java:12780)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.additiveExpression(GroovyRecognizer.java:12450)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.shiftExpression(GroovyRecognizer.java:9664)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.relationalExpression(GroovyRecognizer.java:12355)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.equalityExpression(GroovyRecognizer.java:12279)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.regexExpression(GroovyRecognizer.java:12227)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.andExpression(GroovyRecognizer.java:12195)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.exclusiveOrExpression(GroovyRecognizer.java:12163)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.inclusiveOrExpression(GroovyRecognizer.java:12131)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.logicalAndExpression(GroovyRecognizer.java:12099)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.logicalOrExpression(GroovyRecognizer.java:12067)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.conditionalExpression(GroovyRecognizer.java:4842)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.assignmentExpression(GroovyRecognizer.java:7988)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.expression(GroovyRecognizer.java:9841)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.expressionStatementNoCheck(GroovyRecognizer.java:8314)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.expressionStatement(GroovyRecognizer.java:8739)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.statement(GroovyRecognizer.java:1274)
at org.codehaus.groovy.antlr.parser.GroovyRecognizer.compilationUnit(GroovyRecognizer.java:757)
at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:130)
... 30 more
1 error
;list.join(',')}

Seems that in property expansion the curly braces {} are not allowed inside ${= ... } because ${= close with any } character from any closure, loop, method.. you try to add it.
Also trying to escape the close \} inside ${= ... } does not help.
You can not even use } in a String, the follow code throws the same exception in SOAPUI:
<ns:PRODUCTID>${=return '}'}</ns:PRODUCTID>
The only way that you can use } here seems that is nesting expression like ${= ... ${= ... } }. For example the follow nested exceptions works:
<ns:PRODUCTID>${= 5 + ${= 3+4 } }</ns:PRODUCTID>
// in raw View you will see <ns:PRODUCTID>12</ns:PRODUCTID>
However they also can not help because individually each one has the same problem with } from closures, loops, methods.
Seems that the parser for property expansion which implements SOAPUI can not deal with this. Good catch, maybe you can request a new feature.
I don't add a workaround using groovy script to save the result in a property, and then use it in your request since I'm totally sure that you know how to do it :)

I don't see where the syntax error is either. But try this:
(0..(Math.random() * 5 as Integer)).collect { Math.random() * 1000 as Integer }.join(',')

Related

NodeJS why is object[0] returning '{' instead of the first property from this json object?

So I have to go through a bunch of code to get some data from an iframe. the iframe has a lot of data but in there is an object called '_name'. the first key of name is 'extension_id' and its value is a big long string. the json object is enclosed in apostrophes. I have tried removing the apostrophes but still instead of 'extension_id_output' I get a single curly bracket. the json object looks something like this
Frame {
...
...
_name: '{"extension_id":"a big huge string that I need"} "a bunch of other stuff":"this is a valid json object as confirmed by jsonlint", "globalOptions":{"crev":"1.2.50"}}}'
}
it's a whole big ugly paragraph but I really just need the extension_id. so this is the code I'm currently using after attempt 100 or whatever.
var frames = await page.frames();
// I'm using puppeteer for this part but I don't think that's relevant overall.
var thing = frames[1]._name;
console.log(frames[1])
// console.log(thing)
thing.replace(/'/g, '"')
// this is to remove the apostrophes from the outside of the object. I thought that would change things before. it does not. still outputs a single {
JSON.parse(thing)
console.log(thing[0])
instead of getting a big huge string that I need or whatever is written in extension_id. I get a {. that's it. I think that is because the whole object starts with a curly bracket. this is confirmed to me because console.log(thing[2]) prints e. so what's going on? jsonlint says this is a valid json object but maybe it's just a big string and I should be doing some kind of split to grab whaat's between the first : and the first ,. I'm really not sure.
For two reasons:
object[0] doesn't return the value an object's "first property", it returns the value of the property with the name "0", if any (there probably isn't in your object); and
Because it's JSON, and when you're dealing with JSON in JavaScript code, you are by definition dealing with a string. (More here.) If you want to deal with the object that the JSON describes, parse it.
Here's an example of parsing it and getting the value of the extension_id property from it:
const parsed = JSON.parse(frames[1]._name);
console.log(parsed.extension_id); // The ID

Putting a new function name in an internal macro

trying to write a really basic macro in Rust. I'm trying to turn a multi-line declaration (using nom) into a single line as it's replicated a huge amount. The following is the macro I'm trying to define:
macro_rules! tag_parser {
($name:ident, $tag:expr, $ret:expr) => {
nom::named!(
$name<&str, AnsiSequence>,
nom::do_parse!(
nom::tag!($tag) >>
($ret)
)
);
}
}
And here is an example invocation:
tag_parser!(cursor_restore, "u", AnsiSequence::CursorRestore);
The error I'm getting is the following:
error: no rules expected the token `cursor_restore`
--> src/parsers.rs:95:13
|
95 | tag_parser!(cursor_restore, "u", AnsiSequence::CursorRestore);
| ^^^^^^^^^^^^^^^^ no rules expected this token in macro call
Really, the issue is focused around the first parameter. For some reason it will not let me place it the way I have inside the macro. I'm not sure if this is due to me calling another macro (named!) or something else. Any help would be greatly appreciated, thanks!
I can't tell why the macro expansion fails in the way it does. It does, however, get hung up on the full path to the nom-macro being called in the expansion. If you add use nom::*; to bring do_parse and named into scope beforehand and strip the two nom::-fragments (nom::named!... -> named!...) from the macro-body, it works.

What is the proper way of calling a method in Groovy

In fact, my issue is a lot broader than I could explain in the title. I'm having a problem with understanding a code in Groovy that's supposed to be fairly easy to understand. Please have a look at the following piece of code.
// event handlers are passed the event itself
1:def contactHandler(evt) {
2: log.debug "$evt.value"
3:
4: // The contactSensor capability can be either "open" or "closed"
5: // If it's "open", turn on the light!
6: // If it's "closed" turn the light off.
7: if (evt.value == "open") {
8: switch1.on();
9: } else if (evt.value == "closed") {
10: switch1.off();
11: }
12:}
I can understand everything starting that falls after the line 2, but If lines 8 or 10 are the proper way of calling a method, then what the heck is going on in the line 2? I can understand that log.debug means "debug" function of the class called "log".(Or something similar) But what is that blank space after it? And more than that, why does it say "$evt.value", when it can simply say "evt.value" in lines 8 and 10? And why isn't there a semicolon at the end of the line. I know, they're optional, but as far as I can see there's a convention as to when to use them and when to not. And lastly, I have a stranger line of code which totally insane (to me of course):
11: section ("When the door opens/closes...") {
12: input "contact1", "capability.contactSensor",
13: title: "Where?"
14: }
How should I understand the line starting from 12?
I've taken a look at http://groovy.codehaus.org/ but couldn't decide what to look for in order to find an explanation.
Ok, so from the beginning:
In groovy you can omit parentheses () when calling a method with arguments. So
log.debug 'lol'
is exactly the same as:
log.debug('lol')
Since on() and off() don't have any arguments, there's a need to use parens - or they might be mistaken with on and off fields. Blank separates method from arguments.
evt.value vs "$evt.value" - it's not the same. First is just a literal string, the second one is GString. First will print evt.value while the second one will evaluate the value of value variable for evt object. It might open or closed as further code shows.
Semicolon is optional, that's all I can say. No idea why semicolons are there. Sometimes there's a need to use semicolon - in oneliners e.g.
items.collect { print it; it*it }
Starting from line no.12 it's also a method call. It's equal to:
input("contact1", "capability.contactSensor", title: "Where?")
It's passing a map as the first parameter, and then two strings as the second and third parameters.
Further reading:
Methods - look also for named parameters.
Optionality
All docs

how to handle conditionally existing components in action code?

This is another problem I am facing while migrating from antlr3 to antlr4. This problem is with the java action code for handling conditional components of rules. One example is shown below.
The following grammar+code worked in antlr3. Here, if the unary operator is not present, then a value of '0' is returned, and the java code checks for this value and takes appropriate action.
exprUnary returns [Expr e]
: (unaryOp)? e1=exprAtom
{if($unaryOp.i==0) $e = $e1.e;
else $e = new ExprUnary($unaryOp.i, $e1.e);
}
;
unaryOp returns [int i]
: '-' {$i = 1;}
| '~' {$i = 2;}
;
In antlr4, this code results in a null pointer exception during a run, because 'unaryOp' is 'null' if it is not present. But if I change the code like below, then antlr generation itself reports an error:
if($unaryOp==null) ...
java org.antlr.v4.Tool try.g4
error(67): missing attribute access on rule reference 'unaryOp' in '$unaryOp'
How should the action be coded for antlr4?
Another example of this situation is in if-then-[else] - here $s2 is null in antlr4:
ifStmt returns [Stmt s]
: 'if' '(' e=cond ')' s1=stmt ('else' s2=stmt)?
{$s = new StmtIf($e.e, $s1.s, $s2.s);}
;
NOTE: question 16392152 provides a solution to this question with listeners, but I am not using listeners, my requirement is for this to be handled in the action code.
There are at least two potential ways to correct this:
The "ANTLR 4" way to do it is to create a listener or visitor instead of placing the Java code inside of actions embedded in the grammar itself. This is the only way I would even consider solving the problem in my own grammars.
If you still use an embedded action, the most efficient way to check if the item exists or not is to access the ctx property, e.g. $unaryOp.ctx. This property resolves to the UnaryOpContext you were assuming would be accessible by $unaryOp by itself.
ANTLR expects you access an attribute. Try its text attribute instead: $unaryOp.text==null

What do empty square brackets after a variable name mean in Groovy?

I'm fairly new to groovy, looking at some existing code, and I see this:
def timestamp = event.timestamp[]
I don't understand what the empty square brackets are doing on this line. Note that the timestamp being def'd here should receive a long value.
In this code, event is defined somewhere else in our huge code base, so I'm not sure what it is. I thought it was a map, but when I wrote some separate test code using this notation on a map, the square brackets result in an empty value being assigned to timestamp. In the code above, however, the brackets are necessary to get correct (non-null) values.
Some quick Googling didn't help much (hard to search on "[]").
EDIT: Turns out event and event.timestamp are both zero.core.groovysupport.GCAccessor objects, and as the answer below says, the [] must be calling getAt() on these objects and returning a value (in this case, a long).
The square brackets will invoke the underlying getAt(Object) method of that object, so that line is probably invoking that one.
I made a small script:
class A {
def getAt(p) {
println "getAt: $p"
p
}
}
def a = new A()
b = a[]
println b.getClass()
And it returned the value passed as a parameter. In this case, an ArrayList. Maybe that timestamp object has some metaprogramming on it. What does def timestamp contains after running the code?
Also check your groovy version.
Empty list, found this. Somewhat related/possibly helpful question here.
Not at a computer, but that looks like it's calling the method event.timestamp and passing an empty list as a parameter.
The same as:
def timestamp = event.timestamp( [] )

Resources