I am upgrading Karate from V1.1.0 to V1.3.1 and having issues with javascript functions that were working previously. (I also tested with V1.2.0 and V1.3.0, V1.2.0 was working as expected, V1.3.0 had same issue as V1.3.1)
The issue I seem to have is that functions that are being passed json objects from feature files, now seem to be passed maps, then the functions that do object comparisons are now failing.
I have gone through the V1.3.0 release notes and couldn't see anything that would be affecting it like this. The closest I found was a link to a comment on the Graal upgrade that could affect calling js functions within other js functions (https://github.com/karatelabs/karate/issues/2009#issuecomment-1228632313) but that seemed to be more about how they are called rather than other issues.
In my feature file I have the below code:
* json provider = read('classpath:provider.json')
Given path 'v1', 'ads'
* retry until findObjectInArray(response.adUnits, provider) === true
When method get
Then status 200
The findObjectInArray function lives in its own file that contains the below code:
function findObjectInArray(array, adUnit) {
return !!array.find(unit => equalObjects(unit, adUnit));
}
Then the equalObjects function lives in it's own file with the code below:
function equalObjects(obj1, obj2) {
const objectKeys = Object.keys, typeOfObj1 = typeof obj1, typeOfObj2 = typeof obj2;
return obj1 && obj2 && typeOfObj1 === 'object' && typeOfObj1 === typeOfObj2 ? (
objectKeys(obj1).length === objectKeys(obj2).length &&
objectKeys(obj1).every(key => equalObjects(obj1[key], obj2[key]))
) : (obj1 === obj2);
}
Before upgrading it was working fine, but afterwards the retry condition was never satisfying, and I could see from the responses that the object did exist in the array.
I added some logs to the two functions and found the below differences:
V1.1.0 and V1.2.0:
findObjectInArray values
array = [object Object],[object Object],[object Object],[object Object],[object Object]
adUnit = [object Object]
equalObjects values
obj1 = [object Object]
obj2 = [object Object]
V1.3.0 and V1.3.1:
findObjectInArray values
array = [{"adProvider":"P0","adUnitType":"OUTSTREAM","insertionType":"SSAI","inStreamAdPosition":"MIDROLL","params":{"purchasedEntitlement":"{{purchasedEntitlement}}"}},{"adProvider":"P1","adUnitType":"INSTREAM","insertionType":"CSAI","inStreamAdPosition":"PREROLL","params":{}},{"adProvider":"P2","adUnitType":"INSTREAM","insertionType":"SSAI","inStreamAdPosition":"MIDROLL","params":{}},{"adProvider":"P3","adUnitType":"OUTSTREAM","insertionType":"SSAI","inStreamAdPosition":"MIDROLL","params":{"purchasedEntitlement":"{{purchasedEntitlement}}"}},{"adProvider":"P4","adUnitType":"INSTREAM","insertionType":"SSAI","inStreamAdPosition":"MIDROLL","params":{"purchasedEntitlement":"{{purchasedEntitlement}}"}},{"adProvider":"P5","adUnitType":"OUTSTREAM","insertionType":"SSAI","inStreamAdPosition":"MIDROLL","params":{"videoId":"{{video.id}}"}}]
adUnit = {adProvider=FREE_WHEEL, adUnitType=OUTSTREAM, insertionType=SSAI, inStreamAdPosition=MIDROLL, params={videoId={{video.id}}}}
equalObjects values
obj1 = {adProvider=P0, adUnitType=OUTSTREAM, insertionType=SSAI, inStreamAdPosition=MIDROLL, params={purchasedEntitlement={{purchasedEntitlement}}}}
obj2 = {adProvider=FREE_WHEEL, adUnitType=OUTSTREAM, insertionType=SSAI, inStreamAdPosition=MIDROLL, params={videoId={{video.id}}}}
Because the jsons now seem to be maps, the former string values of the Keys are now being seen as
function () { [native code] }
and not being seen as equal.
Any help would be greatly appreciated, thanks in advance.
Please try 1.4.0.RC3 which has been released. It should solve the issue.
Related
When I' using union type in my graphQL schema I use it typically like this:
const documentTypeDefs = gql`
union TestType = TypeExample1 | TypeExample2
type Document {
exampleKey: TestType
}
`
Then I resolve it like this:
TestType: {
__resolveType(obj) {
if(obj.property1) {
return 'TypeExample1';
}
if(obj.property2) {
return 'TypeExample2';
}
return null;
},
}
But sometimes I'm getting empty object in my resolving function (ie. obj is {}). I thought returning null or undefined will do the job but unfortunately I'm getting error:
"Abstract type ItemsType must resolve to an Object type at runtime for field Document.exampleKey with value {}, received \"{}\". Either the ItemsType type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function."
How can I resolve empty object then?
Thank you!
If an empty object is being passed to __resolveType, that means your field is resolving to an empty object. That means either the value being returned inside your resolver is an empty object, or else the Promise returned is resolving to one.
If you're working with a field that returns a List, it's also possible for just one of the items being returned to be an empty object. This is particularly likely when working with MongoDB if one of the documents you're getting is actually empty or at least missing the fields you've specified in your mongoose schema.
I need help for this kind of error when running this will happen object [] , []
Geocoder.getFromLatLng(28.6139,77.2090).then(
json => {
var addressComponent = json.results[0].address_components[0];
alert(addressComponent);
}, error => {
alert(error+"CATCH");
} )
It looks like you are trying to alert an object doing so usually results in getting the following response:
[object Object]
Which isn't really useful. You can solve this by using JSON.stringify
alert(JSON.stringify(addressComponent)) or alert(JSON.stringify(error))
Doing a reverse geocode lookup on the coordinates gives the following alert when I use JSON.stringify
You can read more about JSON.stringify here in the docs.
The JSON.stringify() method converts a JavaScript object or value to a JSON string
While using alert is useful, I prefer using console.warn as you would get something like this, which means you don't have to stringify every response
I am filtering projects with a computed property like this:
filtered_projects() {
return this.projects.filter( (project) => {
return project.title.toLowerCase().indexOf(this.project_filter.toLowerCase()) !== -1
})
}
When I add a new project using this
submitNewProject() {
let path = '/api/projects';
Vue.http.post(path, this.project)
.then( (rsp) => {
this.projects.push(rsp.data);
this.project = this.getSingleProject();
this.create_project = false;
return true;
});
}
This is giving me an error that I can't find
TypeError: Cannot read property 'toLowerCase' of undefined
It may just be that you are not correctly passing the projects data to the projects array.
Firstly vue-resource now uses body not data to get the response, therefore you may need to use:
this.projects.push(rsp.body)
then this will give you a single array item containing all projects which doesn't look like what you want. I believe instead you're after:
this.projects = rsp.body
Assuming the response body is an array of objects this will then allow:
this.projects.filter(project => {})
to work as expected. Meaning project.title should now be valid
EDIT
For a project title to be set to lowerCase you must be returning an object with a title param, i.e.
rsp.body = {
title: 'FOO',
}
which you'd then set on the projects array via:
this.projects.push(rsp.body)
so the first thing to fix is your response, sort your endpoint so it returns what you are expecting, then the rest of the above code should work
You need preserve "this" before Vue.http.post (self=this) and then in callback change this.projects to self.projects.
Explanation:
How to access the correct `this` context inside a callback?
I'm trying to fetch managed objects from Core Data by their URI. For this I found an Objective-C example of a method (http://www.cocoawithlove.com/2008/08/safely-fetching-nsmanagedobject-by-uri.html) and converted it to Swift ...
func getManagedObjectWithURI(uri:NSURL) -> NSManagedObject?
{
if let psc = persistentStoreCoordinator
{
let objID = psc.managedObjectIDForURIRepresentation(uri);
if (objID != nil)
{
let obj:NSManagedObject = managedObjectContext!.objectWithID(objID!);
if (!obj.fault)
{
return obj;
}
let prd = NSComparisonPredicate(leftExpression: .expressionForEvaluatedObject(), rightExpression: NSExpression(forConstantValue: obj), modifier: .DirectPredicateModifier, type: .EqualToPredicateOperatorType, options: .allZeros);
let req = NSFetchRequest();
req.entity = objID?.entity;
req.predicate = prd;
var results:[NSManagedObject] = managedObjectContext!.executeFetchRequest(req, error: nil) as! [NSManagedObject];
if (!results.isEmpty)
{
return results.first;
}
}
}
return nil;
}
However the method always returns nil, i.e. the fetch request returns empty-handed and I don't know why. Up to the NSFetchRequest everything looks valid. Does anyone has an idea what could be wrong?
Check that the entity and the predicate contain the expected values.
Another suggestion is to write your predicate with NSPredicate(format:) for clarity.
request.predicate = NSPredicate(format: "self = %#", object)
I have changed your variable names for readability.
Solved the issue. It was actually related to another, deeper problem in my core data code explained here: Mac OSX - Core data isn't stored
The above method works fine otherwise.
I apologize if this is a stupid/newb question, but when a Rally query result is returned with a _ref (using the Javascript SDK 1.32), is there a way to directly get the object associated with the _ref?
I see that I can use getRefFromTypeAndObjectId to get the type and the object ID, and then query on that type and object ID to get the object, however I wondered if there was something like getObjectFromRef or some other such way to more directly get back the object associated with the reference.
Excellent question. The getRallyObject method on RallyDataSource should do what you need.
var ref = '/defect/12345.js';
rallyDataSource.getRallyObject(ref, function(result) {
//got it
var name = result.Name;
}, function(response) {
//oh noes... errors
var errors = response.Errors;
});
In SDK 2.0 you use the load method of a data model to read a specific object. Check out this example: http://developer.help.rallydev.com/apps/2.0p5/doc/#!/guide/appsdk_20_data_models