How can I call a function on shell.parse() without first assigning to a variable? for example shell.parse().someFunction() - groovy

Right now I'm doing this:
//main.groovy
def func = shell.parse( new File('func.groovy') )
func.someMethod('sdfsdfsdfsdf')
//func.groovy
def someMethod(deploymentFolder) {
return deploymentFolder
}
I want to make the snippet in main.groovy a one-liner but this does not work:
def func = shell.parse( new File('func.groovy') ).someMethod('sdfsdfsdf')
and this doesn't work either:
def func = shell.parse( new File('func.groovy') ) someMethod('sdfsdfsdf')
Is there a way to call a function directly on what shell.parse returns like this?
Edit
I am calling this in a collect call which seems to change things
So this is not working:
list = arrList.collect { file ->
return shell.parse( new File(file) ).someMethod('sdfsdfsdf')
}
someMethod() returns an arrayList. after collect though list seems to contain the right number of nested lists but they are all null.
Yet doing this actually works:
myarr = []
list = arrList.collect { file ->
tempVar = shell.parse( new File(file) )
myarr += tempVar.someMethod('sdfsdfsdf')
}
I'm not sure what the difference is. I thought collect would do the same thing. It seems to almost do the same thing but the lists it concatenates are all null.

Your first attempt there is right and works as suspected:
def shell = new GroovyShell()
println(["func.groovy"].collect{ it as File }.collect{ shell.parse(it).someMethod('sdfsdfsdfsdf') })
// ⇒ [sdfsdfsdfsdf]

Related

How to use map in groovy

Here is how my script currently looks like -
baseList = readFile('text2.txt').split('\n') as List
def cleanList = []
for (i=0; i < baseList.size; i++) {
if (baseList[i].contains('=')){
cleanList += baseList[i]
}
}
print(cleanList)
This gives following output-
[Pipeline] echo
[version.build=874, version.maintenance=0, version.major=1, version.minor=37]
I want these values to go into another variable called "svnTag"
def svnTag="ccsmp_v_${version.major} ${version.minor} ${version.maintenance} ${version.build}"
So that when I print svnTag, it output something like this-
SVN_TAG=ccsmp_v_1.37.0.846
You are not using a Map, but a List of String, where each element is in the form of <key>=<value>
If you want to parse your file to a Map, you could use something like:
def baseList = readFile('text2.txt').split('\n') as List
def map = [:]
for (el in baseList) {
if (el.contains('=')) {
def parts = el.split('=')
map[parts[0]] = parts[1]
}
}
Then you can use the values from the map with:
def svnTag="ccsmp_v_${map['version.major']} ${map['version.minor']} ${map['version.maintenance']} ${map['version.build']}"
If your file is a valid property file (all lines are in form of key=value), you can use the readProperties step that will create a Properties object for you (that is in fact a Map):
def map = readProperties file: 'text2.txt'

Groovy script to split a file line at ',' and create a new XML file

I am very new to Groovy and trying to figure my way out.
I am trying to write a groovy to split the lines of a file on encountering ',' and then write a if condition based on the first two characters of the line. After that I wanted to create a XML file using the different data in the file. This is how far I have reached.
def Message processData(Message message) {
//Body
def body = message.getBody(java.lang.String)as String;
def varStringWriter = new StringWriter();
def varXMLBuilder = new MarkupBuilder(varStringWriter);
String newItem ;
body.eachLine{
line -> newItem = line ;
String newItem1 = newItem.substring(0,2).trim();
String newItem2 = newItem.substring(3,11).trim();
varXMLBuilder.RECORD{
node1(newItem1);
node2(newItem2);
}
}
def xml = varStringWriter.toString();
xml="<RECORDS>"+xml+"</RECORDS>" ;
message.setBody(xml);
return message;
}
In the above code I tried to use offset but, since each of my file lines are of different length it wont work.
Please help me handle this issue.
Regards,
Nisha
Splitting on a character can be done like this:
data = 'axaratgxrgc,rxregxsergcs'
def lines = data.split(/,/)
assert lines[0] == 'axaratgxrgc'
assert lines[1] == 'rxregxsergcs'
Welcome, first of all, to groovy and Stack Overflow :)
You can use tokenize() to split a string, as shown bellow.
And yeah, don't worry about ; in groovy ;)
def Message processData(Message message) {
//Body
def body = message.getBody(java.lang.String) as String;
def varStringWriter = new StringWriter()
def varXMLBuilder = new MarkupBuilder(varStringWriter)
body.eachLine { line ->
def newItems = line.tokenize(',') // input is a list of chars that will split your string, usually better than .split()
String newItem1 = newItems.first() // looks like you want just two items
String newItem2 = newItems.last() // but you can use as an array as well newItems[0] and newItems[1]
varXMLBuilder.RECORD {
node1(newItem1)
node2(newItem2)
}
}
def xml = varStringWriter.toString()
xml="<RECORDS>${xml}</RECORDS>" // you can use ${} to add a variable inside a string
message.setBody(xml)
return message
}

Checking a value across multiple arrays

I have a context property named 'flights'. I want to check if there is no value for this property, then go to the 'Iteration' test step, else set the first value of the property as a test case property.
Now what I want to do is perform a compare using this test case property value with a couple of arrays. Below is the scenario;
Check if value is in the villas array, if so +1 to VillasCount, else check in hotels array, if in there then +1 to beachCount else +1 to noCount.
Code is below:
// define properties required for the script to run.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath
//Define an empty array list to load data from datasheet
def dataTable_properties = [];
int villasCount = context.getProperty("villasCount")
def lines = new File(dataFolder + "/Test.csv").readLines()
def villas = []
lines.eachWithIndex { line, index ->
if (index) {
def data = line.split(',')*.trim()
if (data[0]) villas << data[0]
}
}
log.info "Villas : ${villas}"
context.setProperty("villasCount", villasCount)
Maybe something like:
for(f in flights){
if(villas.contains(f)){
villasCount = villasCount + 1
}
}
Not 100% sure what you needed to compare, but you could easily expand this to check whatever you wanted.
If this is way off please provide more information on what you were trying to compare.

Access variable value by its name as String (groovy)

I've done some research but I haven't found a working code for my case. I have two variables named test and test2 and I want to put them in a map in the format [test:valueof(test), test2:valueof(test2)]
My piece of code is the following:
def test="HELLO"
def test2="WORLD"
def queryText = "\$\$test\$\$ \$\$test2\$\$ this is my test"
def list = queryText.findAll(/\$\$(.*?)\$\$/)
def map = [:]
list.each{
it = it.replace("\$\$", "")
map.putAt(it, it)
}
queryText = queryText.replaceAll(/\$\$(.*?)\$\$/) { k -> map[k[1]] ?: k[0] }
System.out.println(map)
System.out.println(queryText)
Output:
Desired output:
"HELLO WORLD this is my test"
I think I need something like map.putAt(it, eval(it))
EDIT
This is the way I get my inputs. the code goes into the 'test' script
The ones on the right are the variable names inside the script, the left column are the values (that will later be dynamic)
You are almost there.
The solution is instead of putting the values into separate variables put them into the script binding.
Add this at the beginning ( remove the variables test and test2):
def test="HELLO"
def test2="WORLD"
binding.setProperty('test', test)
binding.setProperty('test2', test2)
and change this:
{ k -> map[k[1]] ?: k[0] }
to this:
{ k -> evaluate(k[1]) }
It should be very simple if you could use TemplateEngine.
def text = '$test $test2 this is my test'
def binding = [test:'HELLO', test2:'WORLD']
def engine = new groovy.text.SimpleTemplateEngine()
def template = engine.createTemplate(text).make(binding)
def result = 'HELLO WORLD this is my test'
assert result == template.toString()
You can test quickly online Demo
Final working code, thanks to all, in particular to dsharew who helped me a lot!
#input String queryText,test,test2,test3
def list = queryText.findAll(/\$\$(.*?)\$\$/)
def map = [:]
list.each{
it = it.replace("\$\$", "")
map.putAt(it, it)
}
queryText = queryText.replaceAll(/\$\$(.*?)\$\$/) { k -> evaluate(k[1]) }
return queryText

Finding a value of a list

I have two lists
def flagList = SystemFlag.list()
this contains the domain objects of one table
I have another list which I create using a query. One of the parameter in the object of this list is contained in the flagList. How can I find if an id of FlagList is present in the second list?
I can do it in plain java but I need to use Groovy for this.
If I understood you correctly you have this situation:
def listeOne = [1,2,3,4,5]
def listTwo = [2,5,1]
You want to see if '2' of 'listTwo' is in 'listOne'.
Find a specific value:
def found = 2 in listTwo //returns a boolean of the interger 2 is in listTwo
Search for common value of both lists:
def intersectionsList = listOne.intersect(listTwo) //gives you a list of value that are in BORTH list
You can also iterate like this:
listTwo.each { value ->
if(value in listOne) println value //or do something lese
}
Alternatively:
listTwo.each { value ->
listOne.find {value}?.toString() //you can perform an action on the object found in listOne. using '?.' will make sure no nullpointer will be thrown if there is no result.
}
I found it using
def it = itemtofindsomehow
list.findIndexof { iterator ->
iterator.domain.id == it.id
}

Resources