Is there something wrong with my code as logic in function works fine in js? - karate

* def a = ["a","b"]
* def b = ["1","2"]
* def fun =
"""
function(a,b){
var result={}
a.forEach(function(x,i){result[x]=b[i]});
return result;}
"""
* def final = fun(a,b)
* print final
Now what I am expecting is
{
"a":"1",
"b":"2"
}
but what I got is {
"a":null,
"b":null
}?

There are limitations to the JS blocks in Karate, that's how it is.
Do this instead:
karate.forEach(a, function(x,i){result[x]=b[i]});

Related

Issue in def variable while performing sort in Karate Framework

I have noticed that while passing a def as a list for simple sorting I am observing that apart from return values the original variable is also sorted.
* def original = ['a','b','c']
* def javaInstance = new (Java.type('package.subpackage.StringSort'))
* def sortedContent = javaInstance.m1(original,'desc');
* print sortedContent
* print original
Both "sortedContent" & "original" def variables are sorted.
Below is the java fn:
public class StringSort {
public List<String> m1(List<String> s, String order) {
Collections.sort(s);
if(order.equals("asc"))
return s;
else {
Collections.reverse(s);
return s;
}
}
}
Output:
sortedContent = ['c','b','a']
original = ['c','b','a']
I don't understand why original def variable is sorted.
That's how Java works. Create a clone:
* def original = ['a','b','c']
* copy temp = original

what to use in place of Object.keys and hasOwnProperty when using karate version 0.9.5?

* def a =
"""
function(ths,tsa,hcia) {
karate.log(JSON.stringify(tsa[hcia[0]],null,2))
var fas = (Object.keys(tsa[hcia[0]]))[0]
karate.log("fas " + fas)
var art = null
for(prtsj in ths[hcia[0]]) {
karate.log(JSON.stringify(ths[hcia[0]][prtsj].sku,null,2))
if((Object.keys(ths[hcia[0]][prtsj].sku)).indexOf(fas) > -1) {
art = ths[hcia[0]][prtsj].type
}
}
return art
}
"""
Please use karate.keysOf() - which will return a JSON array of strings.
Now you can do whatever you want.
Also see: https://stackoverflow.com/a/61139167/143475

Karate: match with parametrized regex

I didn't find the right way to write a match with regexp cointaining a variable:
* def getYear =
"""
function() {
var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
var sdf = new SimpleDateFormat('yyyy');
var date = new java.util.Date();
return sdf.format(date);
}
"""
* def currentYear = getYear()
* def testmatch = { gencode: '#("000" + currentYear + "0000012345")' }
* match testmatch == { gencode: '#regex "[0-9]{3}" + currentYear + "[0-9]{10}"' }
There is a way to do this?
Thanks,
Lorenzo
First, normally when you are doing matches like this, regex is un-necessary, because you might as well do an exact match.
But anyway this is the solution, refer: https://github.com/intuit/karate#self-validation-expressions
* def isValidYear = function(x){ return new RegExp("[0-9]{3}" + currentYear + "[0-9]{10}").test(x) }
* assert isValidYear('00020190000012345')
* match testmatch == { gencode: '#? isValidYear(_)' }

Programally multi-value param

I need to make a request with a multi-value param,its value must be a very big array to test an api param validation. One of my implementation:
Scenario: filter_too_long_multivalue
* def localPath = endPointBase + 'filter'
* def generateLongParam =
"""
function(){
var paramValue = [];
for(var idx = 0; idx<1002; idx++){
paramValue.push('r')
}
var params = {};
params.pl = paramValue;
return params;
}
"""
* def tooLongParam = generateLongParam()
* print tooLongParam
Given path localPath
And params tooLongParam
When method get
Then match response == authorizationSchema.empty
Then the request is:
GET http://XXXXXXXXXXXXX?pl=%5Bobject+Array%5D
I have tried differents ways, but always the same result...
How can I obtain a weel formed request?
Thank you.
Yes, you have hit one of those edge cases, can you let me know if this works, I'll also see if this can be improved.
Sometimes what is returned by a JS function is not exactly the format that Karate likes. The workaround is to use json instead of def to type-convert - refer doc: https://github.com/intuit/karate#type-conversion
* def fun =
"""
function(){
var temp = [];
for(var i = 0; i < 5; i++) {
temp.push('r');
}
return temp;
}
"""
* json array = fun()
Given url demoBaseUrl
And path 'echo'
And params { pl: '#(array)' }
When method get
Then status 200
Which resulted in:
1 > GET http://127.0.0.1:60146/echo?pl=r&pl=r&pl=r&pl=r&pl=r

Get variable dynamically

Is there any way to reference variables dynamically like methods? Here is the Groovy example of referencing a method dynamically:
class Dog {
def bark() { println "woof!" }
def sit() { println "(sitting)" }
def jump() { println "boing!" }
}
def doAction( animal, action ) {
animal."$action"() //action name is passed at invocation
}
def rex = new Dog()
doAction( rex, "bark" ) //prints 'woof!'
doAction( rex, "jump" ) //prints 'boing!'
... But doing something like this doesn't work:
class Cat {
def cat__PurrSound__List = ['a', 'b', 'c']
def cat__MeowSound__List = [1, 2, 3]
def someMethod(def sound) {
assert sound == "PurrSound"
def catSoundListStr = "cat__${obj.domainClass.name}__List"
assert catSoundListStr = "cat__PurrSound__List"
def catSoundList = "$catSoundListStr"
assert catSoundList == cat__PurrSound__List // fail
}
}
Yeah, so you can do:
def methodName = 'someMethod'
assert foo."$methodName"() == "asdf" // This works
and to get the object by name, you can do (in a Script at least):
// Cannot use `def` in a groovy-script when trying to do this
foo = new Foo()
def objectName = 'foo'
assert this."$objectName".someMethod() == "asdf"