How to avoid casting arguments in Spock - groovy

I want to get a List from repository and assert its contents.
In following code I get a warning that states that Object cannot be assigned to List
Is there any way to add better argument to handle such case?
myDomainObjectRepository.save(_) >> { arguments ->
final List<MyDomainObject> myDomainObjects = arguments[0]
assert myDomainObjects == [new MyDomainObject(someId, someData)]
}

To elaborate on Opals answer: There are two parts and a footnote in the docs that are relevant here:
If the closure declares a single untyped parameter, it gets passed the
method’s argument list:
And
In most cases it would be more convenient to have direct access to the
method’s arguments. If the closure declares more than one parameter or
a single typed parameter, method arguments will be mapped one-by-one
to closure parameters[footnote]:
Footnote:
The destructuring semantics for closure arguments come straight from
Groovy.
The problem is that you have a single argument List, and since generics are erased groovy can't decide that you actually want to unwrap the list.
So a single non-List argument works fine:
myDomainObjectRepository.save(_) >> { MyDomainObject myDomainObject ->
assert myDomainObject == new MyDomainObject(someId, someData)
}
or a List argument combined with a second, e.g., save(List domain, boolean flush)
myDomainObjectRepository.save(_, _) >> { List<MyDomainObject> myDomainObjects, boolean flush ->
assert myDomainObjects == [new MyDomainObject(someId, someData)]
}
So the docs are a little bit misleading about this edge case. I'm afraid that you are stuck with casting for this case.
Edit: You should be able to get rid of the IDE warnings if you do this.
myDomainObjectRepository.save(_) >> { List<List<MyDomainObject>> arguments ->
List<MyDomainObject> myDomainObjects = arguments[0]
assert myDomainObjects == [new MyDomainObject(someId, someData)]
}

The docs seems to be precise:
If the closure declares a single untyped parameter, it gets passed the method’s argument list
However I've just changed my spec that uses rightShift + arguments to accept a single type argument and it did work. Try it out.

Related

Reading class method definition - what is Callable?

I am relatively new to python, and I started to read the docs when using packages, but I'm having a hard time understanding some of it:
post_to_main_thread(self: open3d.cpu.pybind.visualization.gui.Application, arg0: open3d::visualization::gui::Window, arg1: Callable[[], None]) → None
the only thing here that I don't understand is the arg1 with that callable, and I can't find an explanation on it at the web.
Interesting question!
So post_to_main_thread() is a method that takes 3 arguments (inputs/variables) and returns None.
Because it's a method (a function associated with a class, not just a standalone function) the first argument, self, refers to the instance of the class that the function is part of.
The other two arguments are passed within the function parentheses, as expected with a standalone function. So a call might look like this:
instance_name = open3d.visualization.gui.Application(...)
instance_name.post_to_main_thread(arg1, arg2)
arg1 should be of type open3d::visualization::gui::Window. This is an instance of the class open3d.visualization.gui.Window().
arg2 should be of type Callable(). This describes a number of built-ins that you can find details about in the documentation. To quote:
The subscription syntax must always be used with exactly two values: the argument list and the return type. The argument list must be a list of types or an ellipsis; the return type must be a single type.
So in this case the type should be Callable[[], None], which means this should be a function that takes no input and returns None. Carrying on from our previous example, you'd pass this as an argument like so:
def my_callable:
print('Hello, World!')
return
instance_name.post_to_main_thread(arg1, my_callable)
Does that clear things up?

Get Parameter list of a closure dynamically in Groovy

I have a Closure defined in a groovy file that load with the shell.evaluate() method.
I need to call this closure in by calling program using the shell."$closurename".call(arguments) call.
However to formulate the closure parameters ( argument above) I'd need to now what are the arguments and arguments names that the closure $Closurename accepts. Is there a way of dynamically knowing this in Groovy? I checked in the metaClass.method property but this does not work in my example below.
Below is the example code.
def arguments;
shell.evaluate(new File("/tmp/myGroovyClosureFile.groovy"))
testBlock = "myClosureName"
//Code here to find the parameters for myClosureName and create
//the arguments variable
shell."$testBlock".call(arguments)
As Jeff mentioned, it seems like groovy when generating code for closures anonymizes somehow the parameter names. However, you can still use reflection to get as much information as you can:
def cl = { int a, String b ->
println(a)
println(b)
}
def callMethod = cl.class.methods.find {
it.name == "call"
}
println callMethod.parameterTypes
println callMethod.parameters.name
and outputs:
[int, class java.lang.String]
[arg0, arg1]
Is there a way of dynamically knowing this in Groovy?
You can't really do it dynamically at runtime.

Passing a def variable to a typed BigDecimal argument in Groovy

I am new to Groovy so I am a bit confused by the run time binding, typed and not typed attributes of the language. Personally I prefer types to be declared.
However, I have a question.
I have a small method that takes some variable from maps, input, whatever, that I know are numbers. Let's say that I don't know what the initial type was (it's somewhere deep in the code or comes from an external source), other that it was a number. Now I have a method that takes two of these arguments and I have to do a modulo operation on them. Because they might be decimal or not, I wrote a small method using the remainder of BigDecimal so to enforce the type I used the type BigDecimal on the method signature.
def callerMethod(Map map) {
...
map.each{
calledMethod(it.val1, it.val2)
...
}
...
}
def calledMethod(BigDecimal val1, BigDecimal val2) {
...
vl1.remainder(val2)
...
}
Is this correct? If the incoming argument is Integer (most of the time the primitives are boxed if I understand it correctly), will it be implicitly cast or turned into a BigDecimal?
How does this work in Groovy.
I still think that since I have the option to use types, I want to use them rather than declaring everything def. It also makes it easier to read code or see what something is if you reading already existing code
The problem in this methods are not the type of variables, is the each of your map
In a groovy Map, the each have two signatures.
One receive a Map.Entry of parameter and other receive key and value
Ex.:
Map map = [key1:'value1',key2:'value2']
map.each{ Map.Entry entryMap ->
println "The value of key: ${entryMap.key} is ${entryMap.value}"
}
The result of this each will be:
The value of key: key1 is value1
The value of key: key2 is value2
Or could be like this
Map map = [key1:'value1',key2:'value2']
map.each{ def key, def value ->
println "The value of key: ${key} is ${value}"
}
And the result of this second will be the same of the first.
If you want to pass two specific arguments to you calledMethod, pass both outside of the each like this:
def callerMethod(Map map) {
calledMethod(map.val1, map.val2)
}
I don't understand perfectly what you want.. I hope that's help you to do you code.

can someone further explain this C# code

I am using the PredicateBuilder class from http://www.albahari.com/nutshell/predicatebuilder.aspx
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
this extension method is chaining Predicates with the OR operator. on the page, the explanation says
We start by invoking the second expression with the first expression’s parameters. An Invoke expression calls another lambda expression using the given expressions as arguments. We can create the conditional expression from the body of the first expression and the invoked version of the second. The final step is to wrap this in a new lambda expression.
so if for example i have
Predicate<Book> p1 = b => b.Title.Contains("economy");
Predicate<Book> p2 = b=>b.PublicationYear>2001;
Predicate chain = p1.And(p2);
I didn't quite get the exlanation. can someone please explain how the code of the extension method above is working?
thanks
Let's rewrite the method body like this:
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
expr1.Body,
Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>())
),
expr1.Parameters);
We should also keep in mind that expr1 is your existing expression that takes a T and returns a bool. Additionally, while the expression trees we are working with do not actually do anything (they represent something instead), I am going to use "do" henceforth because it makes for much easier reading. Technically for an expression tree to actually do something you have to compile it first and then invoke the resulting delegate.
Ok, so what do we have here? This is a lambda expression that takes whatever parameters expr1 takes (see last line) and whose body, as per the documentation, is
a BinaryExpression that represents a conditional OR operation that
evaluates the second operand only if the first operand evaluates to
false.
The first operand is expr1.Body, which means the resulting function (not actually a function, see note above) evaluates expr1. If the result is true it returns true on the spot. Otherwise, it invokes expr2 with the same parameters as those passed to expr1 (this means the single T parameter) and returns the result of that.

EachWithIndex groovy statement

I am new to groovy and I've been facing some issues understanding the each{} and eachwithindex{} statements in groovy.
Are each and eachWithIndex actually methods? If so what are the arguments that they take?
In the groovy documentation there is this certain example:
def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" } //prints each index and number
Well, I see that numbers is an array. What are num and idx in the above statement? What does the -> operator do?
I do know that $idx and $num prints the value, but how is it that idx and num are automatically being associated with the index and contents of the array? What is the logic behind this? Please help.
These are plain methods but they follow quite a specific pattern - they take a Closure as their last argument. A Closure is a piece of functionality that you can pass around and call when applicable.
For example, method eachWithIndex might look like this (roughly):
void eachWithIndex(Closure operation) {
for (int i = 0; this.hasNext(); i++) {
operation(this.next(), i); // Here closure passed as parameter is being called
}
}
This approach allows one to build generic algorithms (like iteration over items) and change the concrete processing logic at runtime by passing different closures.
Regarding the parameters part, as you see in the example above we call the closure (operation) with two parameters - the current element and current index. This means that the eachWithIndex method expects to receive not just any closure but one which would accept these two parameters. From a syntax prospective one defines the parameters during closure definition like this:
{ elem, index ->
// logic
}
So -> is used to separate arguments part of closure definition from its logic. When a closure takes only one argument, its parameter definition can be omitted and then the parameter will be accessible within the closure's scope with the name it (implicit name for the first argument). For example:
[1,2,3].each {
println it
}
It could be rewritten like this:
[1,2,3].each({ elem ->
println elem
})
As you see the Groovy language adds some syntax sugar to make such constructions look prettier.
each and eachWithIndex are, amongst many others, taking so called Closure as an argument. The closure is just a piece of Groovy code wrapped in {} braces. In the code with array:
def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" }
there is only one argument (closure, or more precisely: function), please note that in Groovy () braces are sometime optional. num and idx are just an optional aliases for closure (function) arguments, when we need just one argument, this is equivalent (it is implicit name of the first closure argument, very convenient):
def numbers = [ 5, 7, 9, 12 ]
numbers.each {println "$it" }
References:
http://groovy.codehaus.org/Closures
http://en.wikipedia.org/wiki/First-class_function
Normally, if you are using a functional programing language such as Groovy, you would want to avoid using each and eachWithIndex since they encourage you to modify state within the closure or do things that have side effects.
If possible, you may want to do your operations using other groovy collection methods such as .collect or .inject or findResult etc.
However, to use these for your problem, i.e print the list elements with their index, you will need to use the withIndex method on the original collection which will transform the collection to a collection of pairs of [element, index]
For example,
println(['a', 'b', 'c'].withIndex())
EachWithIndex can be used as follows:
package json
import groovy.json.*
import com.eviware.soapui.support.XmlHolder
def project = testRunner.testCase.testSuite.project
def testCase = testRunner.testCase;
def strArray = new String[200]
//Response for a step you want the json from
def response = context.expand('${Offers#Response#$[\'Data\']}').toString()
def json = new JsonSlurper().parseText(response)
//Value you want to compare with in your array
def offername = project.getPropertyValue("Offername")
log.info(offername)
Boolean flagpresent = false
Boolean flagnotpresent = false
strArray = json.Name
def id = 0;
//To find the offername in the array of offers displayed
strArray.eachWithIndex
{
name, index ->
if("${name}" != offername)
{
flagnotpresent= false;
}
else
{
id = "${index}";
flagpresent = true;
log.info("${index}.${name}")
log.info(id)
}
}

Resources