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
Related
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'
I have list def list = ['values.txt'] and I want to remove extension from filename and receive string . How I can do this ?
Expecting result is -- filename = 'values'.
If you happen to open ANY Groovy book or tutorial you would find a lot of solutions.
For example:
def list = ['values.txt']
def noExtensions = list.collect{ it.split( /\./ )[ 0 ] }
assert ['values'] == noExtensions
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]
def text= '''<Rollback> <Kits>
<Kit ServerName='ust1twastool01a'>
<Backup>2016-10-18_20_34-46-_server-21.000.409_client-21.000.407.zip</Backup>
<Backup>2016-10-18_21_57-33-_server-21.000.409_client-21.000.407.zip</Backup>
<Backup>2016-10-19_02_40-03-_server-21.000.413_client-21.000.407.zip</Backup>
<Backup>2016-10-19_13_58-36-_server-21.000.413_client-21.000.407.zip</Backup>
<Backup>2016-10-20_03_14-34-_server-21.000.413_client-21.000.407.zip</Backup>
</Kit>
<Kit ServerName='another_server'>
<Backup>123123.zip</Backup>
<Backup>321321.zip</Backup>
</Kit>
</Kits></Rollback>'''
def xml = new XmlSlurper().parseText(text)
def map = [:]
i = 0
xml.Kits.Kit.each{node->
def list = []
node.Backup.each{kit->
list.add(kit)
}
map.put(node.#ServerName, list)
}
print map // print map with all keys and values
// Somehow, it's not working ...
print map['ust1twastool01a']
def map2 = ['1':["abc","123"], '2':["bcd", "456"]]
print map2['1']
I have been annoyed by the above code for almost the day. I don't understand why I can't get value by map['ust1twastool01a'].
I attached a screenshot from a console, it shows that map is not empty but just can't get its value by key. map2 is just control group as it has the similar structure to map string as key and list as value
Use as below:
map.put(node.#ServerName.text(), list)
On a side note, I believe you can simplify the code to just:
def xml = new XmlSlurper().parseText(text)
def map = xml.Kits.Kit.collectEntries { node ->
[ node.#ServerName.text(), node.Backup.collect() ]
}
I'm trying to compare two arrays in groovy. My attempts so far have yielded a mixed response and therefore I'm turning to the collective for advice.
In the following code I'm taking 2 REST responses, parsing them and placing everything under the Invoice node into an array. I then further qualify my array so I have a list of InvoiceIDs and then try to compare the results of the two responses to ensure they are the same.
When I compare the array of InvoiceIDs (Guids) they match - this is not what I expect as the invoice order is currently different between my my 2 response sources.
When I sort the arrays of Invoices IDs the results differ.
I'm suspecting my code is faulty, but have spent an hour rattling through it, to no avail.
Any advice on sorting arrays in groovy or on the code below would be most appreciated:
gu = new com.eviware.soapui.support.GroovyUtils( context )
def xmlSlurper = new groovy.util.XmlSlurper()
// Setting up the response parameters
def responseSTAGE = xmlSlurper.parseText(context.expand('${GET Invoices - STAGE#Response}'));
def responseSTAGE2 = xmlSlurper.parseText(context.expand('${GET Invoices - STAGE2#Response}'));
responseInvoicesSTAGE = responseSTAGE.Invoices
responseInvoicesSTAGE2 = responseSTAGE2.Invoices
def arrayOfInvoicesSTAGE = []
def arrayOfInvoicesSTAGE2 = []
def counter = 0
for (invoice in responseInvoicesSTAGE.Invoice) {
arrayOfInvoicesSTAGE[counter] = responseInvoicesSTAGE.Invoice[counter].InvoiceID
//log.info counter+" STAGE"+arrayOfInvoicesSTAGE[counter]
arrayOfInvoicesSTAGE2[counter] = responseInvoicesSTAGE2.Invoice[counter].InvoiceID
//log.info counter+" STAGE2"+arrayOfInvoicesSTAGE2[counter]
counter++
}
log.info arrayOfInvoicesSTAGE
log.info arrayOfInvoicesSTAGE2
def sortedSTAGE = arrayOfInvoicesSTAGE.sort()
def sortedSTAGE2 = arrayOfInvoicesSTAGE2.sort()
log.info sortedSTAGE
As an aside, can't you replace:
def arrayOfInvoicesSTAGE = []
def arrayOfInvoicesSTAGE2 = []
def counter = 0
for (invoice in responseInvoicesSTAGE.Invoice) {
arrayOfInvoicesSTAGE[counter] = responseInvoicesSTAGE.Invoice[counter].InvoiceID
//log.info counter+" STAGE"+arrayOfInvoicesSTAGE[counter]
arrayOfInvoicesSTAGE2[counter] = responseInvoicesSTAGE2.Invoice[counter].InvoiceID
//log.info counter+" STAGE2"+arrayOfInvoicesSTAGE2[counter]
counter++
}
with
def arrayOfInvoicesSTAGE = responseInvoicesSTAGE.Invoice*.InvoiceID
def arrayOfInvoicesSTAGE2 = responseInvoicesSTAGE2.Invoice*.InvoiceID
Two arrays are considered equal in Groovy if they have they have the same number of elements and each element in the same position are equal. You can verify this by running the following code in the Groovy console
Integer[] foo = [1,2,3,4]
Integer[] bar = [4,3,2,1]
assert foo != bar
bar.sort()
assert foo == bar